首页 > 解决方案 > 从 Future / Stream 返回字符串列表

问题描述

我的问题与此处此处提到的问题非常相似,但由于某种原因,这些对我不起作用。

基本上,我想做一些简单的 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,尽管实际方法工作正常,即如果我将打印语句放在我有 _dirs.add() 的地方我可以看到添加了正确的目录,_dirs 包含我想要的,但我不知道如何返回完成的 _dirs 列表)。我尝试以与上述帖子类似的方式做一些事情,其中​​使用了 Completer(我收到错误消息“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() 函数保持不变。谁能指出我的逻辑哪里出错了?

标签: dartflutter

解决方案


您正在设置一个侦听器,然后在收到任何结果之前立即返回 - 这就是为什么您的返回总是空的。的主体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

推荐阅读