37

我想使用 Dart 列出一个目录(在文件系统上)的所有内容。我怎样才能做到这一点?

4

8 回答 8

24

API 已更改,我已更新 M4 版本 (0.5.16_r23799) 的异步代码:

Future<List<FileSystemEntity>> dirContents(Directory dir) {
  var files = <FileSystemEntity>[];
  var completer = Completer<List<FileSystemEntity>>();
  var lister = dir.list(recursive: false);
  lister.listen ( 
      (file) => files.add(file),
      // should also register onError
      onDone:   () => completer.complete(files)
      );
  return completer.future;
}
于 2013-06-13T07:51:50.430 回答
23

如何在 Dart 中列出目录的内容

final dir = Directory('path/to/directory');
final List<FileSystemEntity> entities = await dir.list().toList();

这会从路径创建一个目录。然后它将其转换为 的列表FileSystemEntity,该列表可以是 a File、 aDirectory或 a Link。默认情况下,子目录不会递归列出。

如果要打印该列表,请添加以下行:

entities.forEach(print);

如果您只想获取文件,那么您可以这样做:

final Iterable<File> files = entities.whereType<File>();
于 2020-01-23T00:47:10.020 回答
18

list方法返回一个Stream,其中每个发出的事件都是一个目录条目:

Directory dir = Directory('.');
// execute an action on each entry
dir.list(recursive: false).forEach((f) {
  print(f);
});

顾名思义,listSyncmethod 是阻塞版本:

// create a list of entries
List<FileSystemEntity> entries = dir.listSync(recursive: false).toList();

使用什么方法取决于应用程序上下文。直接来自文档的注释:

除非您有特定原因使用方法的同步版本,否则请首选异步版本以避免阻塞您的程序。

于 2019-02-14T14:04:10.337 回答
12

这个答案已经过时了。请参阅已接受的答案。

有两种方法可以使用 Dart VM 和dart:io库列出目录的内容。

(注意:以下内容仅在命令行上运行或作为服务器端应用程序运行时在 Dart VM 中有效。这在浏览器中或编译为 JavaScript 时无效。)

设置

首先,您需要导入dart:io库。该库包含访问文件、目录等所需的类。

import 'dart:io';

其次,创建Directory该类的新实例。

var dir = new Directory('path/to/my/dir');

在脚本中列出内容

最简单的方法是使用新listSync方法。这将返回一个内容列表。默认情况下,这不会递归。

List contents = dir.listSync();
for (var fileOrDir in contents) {
  if (fileOrDir is File) {
    print(fileOrDir.name);
  } else if (fileOrDir is Directory) {
    print(fileOrDir.path);
  }
}

如果你想通过目录递归,你可以使用可选参数recursive

List allContents = dir.listSync(recursive: true);

警告如果你的目录结构有循环符号链接,上面的代码将会崩溃,因为它递归地跟随符号链接。

listSync当您使用 Dart 编写 shell 脚本、命令行实用程序或类似的应用程序或脚本时,这种使用 的方法特别有用。

列出服务器中的内容

列出目录内容的第二种方法是使用list. 当您需要列出目录以响应 HTTP 请求时,您将使用第二种方法。请记住,Dart 的每个隔离都在单个线程中运行。任何长时间运行的进程都可能阻塞事件循环。当交互性很重要,或者从单个 Dart 脚本为大量客户端提供服务时,请使用异步版本。

使用异步版本,dir.list()返回一个DirectoryLister. 您可以在 DirectoryLister 上注册三个不同的回调:

  • onFile: 遇到文件或目录时调用
  • onDone:当目录列表器完成列出内容时调用
  • onError: 当列表器遇到一些错误时调用

这是一个简单的函数,它返回一个字符串列表的 Future,其中包含目录中的文件名:

Future<List<String>> dirContents(Directory dir) {
  var filenames = <String>[];
  var completer = new Completer();
  var lister = dir.list();
  lister.onFile = (filename) => filenames.add(filename);
  // should also register onError
  lister.onDone = (_) => completer.complete(filenames);
  return completer.future;
}

当然,这种方法对于服务器来说是完美的,对于简单的脚本就比较麻烦了。

幸运的是,Dart 支持这两种方法供您使用!

于 2013-01-10T23:10:30.050 回答
4

里面和异步函数写这个

List<FileSystemEntity> allContents = await Directory("folder/path").list().toList();

现在你有一个包含所有内容的列表

于 2020-09-30T17:40:07.743 回答
3

这是我使用 async/await 的版本,仅返回文件列表:

List<File> filesInDirectory(Directory dir) async {
  List<File> files = <File>[];
  await for (FileSystemEntity entity in dir.list(recursive: false, followLinks: false)) {
    FileSystemEntityType type = await FileSystemEntity.type(entity.path);
    if (type == FileSystemEntityType.FILE) {
      files.add(entity);
      print(entity.path);
    }
  }
  return files;
}
于 2015-09-16T12:20:47.350 回答
3

使用此功能,您可以打印一个目录的所有目录和文件。你只需要传递一个特定的路径。

Future listDir(String folderPath) async {
  var directory = new Directory(folderPath);
  print(directory);

  var exists = await directory.exists();
  if (exists) {
    print("exits");

    directory
      .list(recursive: true, followLinks: false)
      .listen((FileSystemEntity entity) {
        print(entity.path);
      });
  }
}
于 2017-04-02T02:52:51.253 回答
1

要获取具有特定字符串的文件名列表,可以使用以下代码:

String directory = (await getApplicationDocumentsDirectory()).path;
List<FileSystemEntity> files = Directory(directory).listSync(recursive: false);

List<String> filePaths = [];
for (var fileSystemEntity in files) {
  if (basename(fileSystemEntity.path).contains('mystring')) {
    filePaths.add(fileSystemEntity.path);
  }
}

如果您只需要文件名而不是整个路径,则可以使用 basename 函数。

于 2020-05-17T16:01:51.143 回答