我的问题与提到的问题非常相似 here和 here ,但出于某种原因,这些对我不起作用。
基本上,我想做一些简单的 I/O 操作(在移动设备上),返回包含特定文件格式的字符串列表(文件夹路径)(假设为了论证我想找到所有mp3 文件)。
这是我的代码
Future<List<String>> getFolders() async {
List<String> _dirs = new List();
await SimplePermissions.requestPermission(Permission.ReadExternalStorage);
_dirs = await findAllFolders();
return _dirs;
}
Future<List<String>> findAllFolders() async {
Directory _root = Directory("/sdcard");
bool _notInList = true;
List<String> _dirs = new List();
_root.list(recursive: true, followLinks: false)
.listen((FileSystemEntity entity) {
if(entity.toString().contains("mp3")) {
if(_dirs.length==0) {
_dirs.add(entity.parent.path.toString());
} else {
_notInList = true;
for (var i = 0; i < _dirs.length; ++i) {
if(_dirs[i] == entity.parent.path.toString()) {
_notInList = false;
}
}
if(_notInList) {
_dirs.add(entity.parent.path.toString());
}
}
}
});
return _dirs;
}
我想在 getFolders() 之外使用 _dirs 的地方。
我知道 findAllFolders() 在我的 listen() 事件完成之前立即返回 _dirs(因此它的长度始终为 0,尽管实际方法工作正常,即如果我将 print 语句放在我有 _dirs.add( ) 我可以看到添加了正确的目录,_dirs 包含我想要的但我不知道如何返回完成的 _dirs 列表)。我尝试以与上面提到的帖子类似的方式做一些事情,其中使用了完成者(我收到一条错误消息“Bad State:Future already completed”)。相应的代码是
Future<List<String>> findAllFolders() async {
Directory _root = Directory("/sdcard");
bool _notInList = true;
List<String> _dirs = new List();
Completer<List<String>> _completer = new Completer<List<String>>();
_root.list(recursive: true, followLinks: false)
.listen((FileSystemEntity entity) {
if(entity.toString().contains("mp3")) {
if(_dirs.length==0) {
_dirs.add(entity.parent.path.toString());
} else {
_notInList = true;
for (var i = 0; i < _dirs.length; ++i) {
if(_dirs[i] == entity.parent.path.toString()) {
_notInList = false;
}
}
if(_notInList) {
_dirs.add(entity.parent.path.toString());
}
}
}
_completer.complete(_dirs);
});
return _completer.future;
}
在这种情况下,getFolders() 函数保持不变。谁能指出我的逻辑哪里出了问题?
最佳答案
您正在设置一个监听器,然后在收到任何结果之前立即返回 - 这就是您的返回始终为空的原因。 findAllFolders()
的主体需要等待响应才能返回。尝试以下替换 _root.list().listen()
:
List<FileSystemEntity> files = await _root.list(recursive: true, followLinks: false).toList();
for (FileSystemEntity entity in files) {
// Do your filename logic and populate _dirs
关于dart - 从 Future/Stream 返回字符串列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54840514/