我想使用Dart列出目录(在文件系统上)的所有内容。我怎么能这样做?
答案 0 :(得分:8)
使用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
:当目录lister完成列出内容时调用onError
:当Lister遇到一些错误时调用这是一个简单的函数,它返回一个字符串列表的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支持两种方法供您使用!
答案 1 :(得分:4)
API已更改,我已更新M4版本的异步代码(0.5.16_r23799):
Future<List<FileSystemEntity>> dirContents(Directory dir) {
var files = <FileSystemEntity>[];
var completer = new Completer();
var lister = dir.list(recursive: false);
lister.listen (
(file) => files.add(file),
// should also register onError
onDone: () => completer.complete(files)
);
return completer.future;
}
答案 2 :(得分:4)
final dir = Directory('path/to/directory');
final files = await dir.list().toList();
这将从路径创建目录。然后,它将其转换为FileSystemEntity
的列表,该列表可以是File
,Directory
或Link
。 (因此,即使我在示例中说了files
,它也可能包含Directory
或Link
。)默认情况下,不会递归列出子目录。
如果要打印该列表,请添加以下行:
files.forEach(print);
答案 3 :(得分:1)
这是我的版本使用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;
}
答案 4 :(得分:1)
使用此功能,您可以打印目录的所有目录和文件。 你只需要传递一条特定的路径。
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);
});
}
}
答案 5 :(得分:0)
list
方法返回一个Stream
,其中每个发出的事件都是一个目录条目:
Directory dir = Directory('.');
// execute an action on each entry
dir.list(recursive: false).forEach((f) {
print(f);
});
顾名思义,listSync
方法是阻止版本:
// create a list of entries
List<FileSystemEntity> entries = dir.listSync(recursive: false).toList();
使用哪种方法取决于应用程序上下文。直接来自docs的注释:
除非有特定的原因要使用方法的同步版本,否则最好使用异步版本以避免阻塞程序。
答案 6 :(得分:0)
要获取具有特定字符串的文件名列表,可以使用以下代码:
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函数。
答案 7 :(得分:0)
内部和异步函数编写
List<FileSystemEntity> allContents = await Directory(dcim).list().toList();
现在您有了一个包含所有内容的列表