How do I get the directory of the current script, in Dart?

If you're doing this for a console based app (e.g. in a unit test) and intend to use the output to open a file for reading or writing, it's more helpful to use 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'));
}

The result of that command can be used with a File object and be opened/read (e.g. if you have a unit test that needs to read/compare sample data, or a console program that needs to open a file relative to the current script for some other reason).


The easiest way to find the script's directory is to use the path package.

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

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

Put the path package into your pubspec.yaml:

dependencies:
  path: any

And be sure to run pub get to download and link the path package.


Using Platform.script.path doesn't work in all circumstances.

If your script is compiled or running as a unit test you won't get the expected results.

This is from the dcli project (https://pub.dev/packages/dcli)

If you are using dcli you can call:

// absolute path including the script name
DartScript.self.pathToScript;

or

// just the absolute path to the script's directory
DartScript.self.pathToScriptDirectory;

This code works if the script is run via dart <scriptname.dart>, if you compile the script or if you script is a unit test.

Here is the internal implementation.

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);

Another (albeit hacky) way to determine the path to the current .dart file is to extract the path from the stack trace.

Unlike Platform.script.path, this should work with unit tests:

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

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

Note that this will return a path relative to (I think) the caller's package root. Also note that stacktrace.Frame.caller(1).library returns the path to the caller, so the above expects that you call currentDartFilePath() and not stacktrace.Frame.caller(1).library directly.

If you want just the directory, you then can perform typical path manipulation operations on the result.

Tags:

Dart

Dart Io