create_ method

Future<void> create_()

Creates the File.

Implementation

Future<void> create_() async {
  if (Platform.isWindows) {
    // On Windows, \\?\ prefix causes issues if we use it to access a root volume without a trailing slash.
    // In other words, \\?\C: is not valid, but \\?\C:\ is valid. If we try to access \\?\C: without a trailing slash, following error is thrown by Windows:
    //
    // "\\?\C:" is not a recognized device.
    // The filename, directory name, or volume label syntax is incorrect.
    //
    // When recursively creating a [File] or [Directory] recursively using `dart:io`'s implementation, if the parent [Directory] does not exist, all the intermediate [Directory]s are created.
    // However, internal implementation of `dart:io` does not handle the case of \\?\C: (without a trailing slash) & fails with the above error.
    // To avoid this, we manually create the intermediate [Directory]s with the trailing slash.
    final file = File(clean(path));
    Directory parent = file.parent;
    // Add trailing slash if not present.
    if (!parent.path.endsWith('\\')) {
      parent = Directory('${parent.path}\\');
    }
    // [File] already exists.
    if (await file.exists_()) {
      return;
    }
    // Parent [Directory] exists, no need to create intermediate [Directory]s. Just create the [File].
    else if (await parent.exists_()) {
      await file.create();
    }
    // Parent [Directory] does not exist, create intermediate [Directory]s & then create the [File].
    else {
      String path = file.path.startsWith(kWin32LocalPathPrefix)
          ? file.path.substring(kWin32LocalPathPrefix.length)
          : file.path;
      if (path.endsWith('\\')) {
        path = path.substring(0, path.length - 1);
      }
      final parts = path.split('\\');
      parts.removeLast();
      for (int i = 0; i < parts.length; i++) {
        final intermediate =
            '$kWin32LocalPathPrefix${parts.sublist(0, i + 1).join('\\')}\\';
        try {
          if (!await Directory(intermediate).exists_()) {
            await Directory(intermediate).create();
          }
        } catch (exception, stacktrace) {
          print(exception.toString());
          print(stacktrace.toString());
        }
      }
      // Finally create the [File].
      await file.create();
    }
  } else {
    try {
      await File(clean(path)).create(recursive: true);
    } catch (exception, stacktrace) {
      print(exception.toString());
      print(stacktrace.toString());
    }
  }
}