Dart を使用して、(ファイル システム上の) ディレクトリのすべての内容を一覧表示したいと考えています。これどうやってするの?
8 に答える
この回答は古くなっています。受け入れられた回答をご覧ください。
Dart VM とdart:io
ライブラリを使用してディレクトリの内容を一覧表示するには、2 つの方法があります。
(注: 以下は、コマンドラインまたはサーバー側アプリとして実行されている場合にのみ、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 で作成する場合に特に便利です。
サーバー内のコンテンツの一覧表示
ディレクトリの内容を一覧表示する 2 つ目の方法は、 の非同期バージョンを使用することですlist
。たとえば、HTTP 要求に応答してディレクトリを一覧表示する必要がある場合は、この 2 番目の方法を使用します。Dart のアイソレートはそれぞれ 1 つのスレッドで実行されることに注意してください。実行時間の長いプロセスは、イベント ループをブロックする可能性があります。対話性が重要な場合、または単一の Dart スクリプトから多くのクライアントにサービスを提供する場合は、非同期バージョンを使用します。
非同期バージョンでは、 をdir.list()
返しますDirectoryLister
。DirectoryLister には 3 つの異なるコールバックを登録できます。
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 は両方の方法をサポートしています。
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;
}
特定の文字列を含むファイル名のリストを取得するには、次のコードを使用できます。
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 関数を使用できます。