如何有效地列出目录中的所有文件,包括子目录? [英] How to list all files inside a directory including sub-directories efficiently?

查看:26
本文介绍了如何有效地列出目录中的所有文件,包括子目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个图库应用,该应用可显示手机或笔式驱动器中的所有图像.我成功地列出了所有图像并将其显示到应用程序中.但我认为它很慢.我在 AsyncTask 中使用了 Depth First Search 技术.那么有没有其他方法可以在 AsyncTask 中使用,它的速度要快得多.这里的根是一个由树 URI 组成的 DocumentFile.

I'm working on a gallery app which displays all the images in a phone or a pen-drive. I successfully managed to list all the images and displays it into the app. But I think it is pretty slow. I'm using Depth First Search technique inside an AsyncTask. So is there any other method which can be used inside AsyncTask which is much faster. Here root is a DocumentFile which is made from a tree URI.

这是我使用过的代码.

public class ImageBackgroundTask extends AsyncTask<Object, Object, ArrayList<DocumentFile>> {
DocumentFile root;
ArrayList<DocumentFile> result;
ProgressDialog pg;
Context context;
private AsyncTaskCompleteListener<ArrayList<DocumentFile> > callback;

ImageBackgroundTask(DocumentFile root, Context context, AsyncTaskCompleteListener<ArrayList<DocumentFile>> cb){
    this.context=context;
    this.root=root;
    this.callback = cb;

}
@Override
protected ArrayList<DocumentFile> doInBackground(Object... voids) {
    Queue<DocumentFile> stack=new ArrayDeque<>();
    ArrayList<DocumentFile> list=new ArrayList<>();
    for(DocumentFile f:root.listFiles()){
        stack.add(f);
    }
    while(!stack.isEmpty()){
        DocumentFile child=stack.remove();
        if(child.isDirectory()){
            for(DocumentFile file:child.listFiles()){
                stack.add(file);
            }
        }
        else if(child.isFile()){
            String name=child.getName();
            if(name.endsWith(".jpg")
                    || name.endsWith(".png")
                    || name.endsWith("jpeg")
                    || name.endsWith("JPG")
                    || name.endsWith("JPEG")
                    || name.endsWith("PNG"))
                list.add(child);
        }
    }
    return list;
}

@Override
protected void onPreExecute() {
    pg=new ProgressDialog(context);
    pg.setMessage("Loading...");
    pg.show();

}

@Override
protected void onProgressUpdate(Object... values) {
    super.onProgressUpdate(values);
}

@Override
protected void onPostExecute(ArrayList<DocumentFile> aVoid) {
    pg.dismiss();
    result=aVoid;
    callback.onTaskComplete(result);

}

这是输出.

查看 GIF

推荐答案

不要使用 DocumentFile.listFiles() 列出您使用 Intent.ACTION_OPEN_DOCUMENT_TREE<获取的树 uri 的文件/代码>.

Do not use DocumentFile.listFiles() to list the files for a tree uri you obtained with Intent.ACTION_OPEN_DOCUMENT_TREE.

因为它是出了名的慢.

改为使用 DocumentsContract 中的函数.

Instead use functions from DocumentsContract.

查看 使用 MTP 使用 Android Storage Access Framework/DocumentProvider 遍历目录层次结构的问题

Look at the void traverseDirectoryEntries(Uri rootUri) function from Issues traversing through directory hierarchy with Android Storage Access Framework / DocumentProvider using MTP

为每个文件收集子 uri,而不是尝试为其获取 DocumentFile.

Collect the child uri for every file instead of trying to obtain a DocumentFile for it.

然后您可以使用该子 uri 加载图像.

Then later you can use that child uri to load the image.

如果你现在需要六秒钟,那么我认为 DocumentsContract 不到一秒钟.

If you need six seconds now then it will be less than a second with DocumentsContract i think.

这篇关于如何有效地列出目录中的所有文件,包括子目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆