Как мне получить каталог текущего скрипта в Dart?

Я хочу знать, что каталог сценария. У меня есть сценарий командной строки Dart.

4 ответа

Решение

Самый простой способ найти каталог скрипта - использовать пакет path.

import "package:path/path.dart" show dirname;
import 'dart:io' show Platform;

main() {
  print(dirname(Platform.script.toString()));
}

Поместите пакет пути в ваш pubspec.yaml:

dependencies:
  path: any

И обязательно беги pub get скачать и связать путь пакета.

Если вы делаете это для консольного приложения (например, в модульном тесте) и намереваетесь использовать вывод, чтобы открыть файл для чтения или записи, более полезно использовать Platform.script.path:

import "package:path/path.dart" show dirname, join;
import 'dart:io' show Platform;

main() {
  print(join(dirname(Platform.script.path), 'test_data_file.dat');
}

Результат этой команды может быть использован с File объект и быть открытым / прочитанным (например, если у вас есть модульный тест, который должен прочитать / сравнить пример данных, или консольная программа, которая должна открыть файл относительно текущего скрипта по какой-то другой причине).

Использование Platform.script.path работает не во всех случаях.

Если ваш скрипт скомпилирован или запущен как модульный тест, вы не получите ожидаемых результатов.

Это из проекта dcli (https://pub.dev/packages/dcli)

Если вы используете dcli, вы можете позвонить:

      // absolute path including the script name
Script.current.pathToScript;

или же

      // just the absolute path to the script's directory
Script.current.pathToScriptDirectory;

Этот код работает, если сценарий запускается через dart <scriptname.dart>, если вы компилируете сценарий или если сценарий является модульным тестом.

Вот внутренняя реализация.

      static String get _pathToCurrentScript {
    if (_current == null) {
      final script = Platform.script;

      String _pathToScript;
      if (script.isScheme('file')) {
        _pathToScript = Platform.script.path;

        if (_isCompiled) {
          _pathToScript = Platform.resolvedExecutable;
        }
      } else {
        /// when running in a unit test we can end up with a 'data' scheme
        if (script.isScheme('data')) {
          final start = script.path.indexOf('file:');
          final end = script.path.lastIndexOf('.dart');
          final fileUri = script.path.substring(start, end + 5);

          /// now parse the remaining uri to a path.
          _pathToScript = Uri.parse(fileUri).toFilePath();
        }
      }

      return _pathToScript;
    } else {
      return _current.pathToScript;
    }
  }

  static bool get _isCompiled =>
      basename(Platform.resolvedExecutable) ==
      basename(Platform.script.path);

Еще один (пусть и хакерский) способ определения пути к текущему .dart файл должен извлечь путь из трассировки стека.

в отличие Platform.script.path, это должно работать с модульными тестами:

      import 'package:stack_trace/stack_trace.dart' as stacktrace;

String currentDartFilePath() => stacktrace.Frame.caller(1).library;

Обратите внимание, что это вернет путь относительно (я думаю) корня пакета вызывающего.

Если вам нужен только каталог, вы можете выполнить типичные операции манипулирования путями с результатом.

Другие вопросы по тегам