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

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


person Seth Ladd    schedule 27.10.2013    source источник


Ответы (4)


Если вы делаете это для консольного приложения (например, в модульном тесте) и собираетесь использовать вывод, чтобы открыть файл для чтения или записи, более полезно использовать 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 и открыть/прочитать (например, если у вас есть модульный тест, который должен читать/сравнивать образцы данных, или консольная программа, которой нужно открыть файл относительно текущего скрипта для какая-то другая причина).

person Dan Field    schedule 20.04.2018

Самый простой способ найти каталог скрипта — использовать пакет 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, чтобы загрузить и связать пакет пути.

person Seth Ladd    schedule 27.10.2013
comment
Вы задали этот вопрос себе 27 октября, а 26 октября было объявлено, что класс Platform будет переведен в отдельный пакет package. Может быть, вы объявите об этих изменениях? - person mezoni; 28.10.2013
comment
Я думаю, что это решение было отменено. Платформа находится в dart:io - person Seth Ladd; 31.10.2013
comment
Я получил результат с префиксом file://. Небольшое улучшение для меня заключалось в том, чтобы вместо этого использовать Platform.script.path. - person tishma; 11.04.2018
comment
Индикатор любой версии используется недостаточно - person ; 19.03.2020
comment
как насчет файла:///, это нужно исправить - person Raiden Core; 10.05.2020
comment
Следует отметить, что если скрипт скомпилирован, то Platform.script.path возвращает текущий рабочий каталог, а не фактический путь к скрипту. - person Brett Sutton; 13.01.2021

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

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

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

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

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

or

// 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.toFilePath();

        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);
person Brett Sutton    schedule 13.01.2021
comment
этот проект потрясающий - person Hitesh Kumar Saini; 05.05.2021

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

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

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

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

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

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

person jamesdlin    schedule 25.05.2021