我的问题与提到的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的地方。
我知道在我的listen()事件完成之前,findAllFolders()立即返回_dirs(因此,其长度始终为0,尽管实际方法可以正常工作,即,如果我将打印语句放在我有_dirs.add( )我可以看到添加了正确的目录,_dirs包含了我想要的内容,但是我不知道如何返回完成的_dirs列表)。我试图以与上述文章类似的方式执行某项操作,其中使用了Completer(我收到一条错误消息“错误状态:未来已完成”)。相应的代码将是
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()函数保持不变。谁能指出我的逻辑出了什么问题?
答案 0 :(得分:1)
您要设置一个侦听器,然后在返回任何结果之前立即返回-这就是您的返回始终为空的原因。 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