1

我目前正在为 android 开发一个基本的文件浏览器。我有一个用于复制文件的工作版本,但是当它通过目录工作时,它会复制它找到的文件。我想更改它,以便在开始复制之前找到所有文件的总大小,以帮助获得更好的进度条。

如果有另一种方法来查找目录的总大小及其所有内容?

这是我当前的版本。我无法更改此设置,我尝试使用 arrayList 但是当我尝试在最后复制文件时,我认为他们试图以错误的顺序复制。

public void copyDirectory(File sourceLocation , File targetLocation) throws IOException {
        if (sourceLocation.isDirectory()) {
            if (!targetLocation.exists() && !targetLocation.mkdirs()) {
                throw new IOException("Cannot create directory: " + targetLocation.getAbsolutePath());
            }

            String[] children = sourceLocation.list();
            for (int i = 0; i < children.length; i++) {
                copyDirectory(new File(sourceLocation, children[i]),
                        new File(targetLocation, children[i]));
            }
        } else {                
            File directory = targetLocation.getParentFile();
            if (directory != null && !directory.exists() && !directory.mkdirs()) {
                throw new IOException("Cannot create directory: " + directory.getAbsolutePath());
            }

            FileInputStream in = new FileInputStream(sourceLocation);
            FileOutputStream out = new FileOutputStream(targetLocation);

            long fileLength = sourceLocation.length();

            byte[] buf = new byte[1024];
            long total = 0;
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
                total += len;
                publishProgress((int) (total * 100 / fileLength));
            }
            in.close();
            out.close();
        }
    }

解决方案

jtwigg的回答也应该有效。我只是想我会添加我找到的解决方案。无法回答我自己的问题,所以我将其放在这里。

遍历目录中的所有文件并保持运行总数似乎可行。虽然它需要先循环大小,然后再实际复制文件。只需在调用 copyDirectory() 之前使用要复制的文件或目录调用 getDirectorySize()。

private void getDirectorySize(File sourceLocation) throws IOException {
        if (sourceLocation.isDirectory()) {
            String[] children = sourceLocation.list();
            for (int i = 0; i < children.length; i++) {
                getDirectorySize(new File(sourceLocation, children[i]));
            }
        } else {
            totalFileSize += sourceLocation.length();
        }
}

该函数将需要全局 long totalFileSize,然后只需要替换:

publishProgress((int) (total * 100 / fileLength));

和:

publishProgress((int) (total * 100 / totalFileSize));
4

1 回答 1

2

如果我理解正确,您希望找到目录中所有文件的总大小,然后复制它们。我会创建另一个函数,例如:

public void beginCopy(File source, File destination)
{
    ArrayList<PendingFile> filesToCopy = new ArrayList<PendingFile>();
    long totalSize = copyDirectory(source, destination, filesToCopy);
    // totalsize now contains the size of all the files
    // files to copy now contains a list of source and destination files

    // now modifying your copy method we can copy all the files
    long totalThusFar = 0;
    for (PendingFile pending : filesToCopy)
    {
        FileInputStream in = new FileInputStream(pending.source);
        FileOutputStream out = new FileOutputStream(pending.destination);

        long fileLength = sourceLocation.length();

        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
            totalThusFar += len;
            publishProgress((int) (total * 100 / totalsize));
        }
        in.close();
        out.close();
    }
}

您将需要一个 PendingFile 类/结构来保存源和目标。您将在复制方法中将它们添加到 ArrayList 中,如下所示:

public long copyDirectory(File sourceLocation , File targetLocation, ArrayList list) throws IOException {
    if (sourceLocation.isDirectory()) {
        if (!targetLocation.exists() && !targetLocation.mkdirs()) {
            throw new IOException("Cannot create directory: " + targetLocation.getAbsolutePath());
        }

        String[] children = sourceLocation.list();
        long totalSize = 0;
        for (int i = 0; i < children.length; i++) {
            totalSize += copyDirectory(new File(sourceLocation, children[i]),
                    new File(targetLocation, children[i]), list);
            return totalSize;
        }
    } else {                
        File directory = targetLocation.getParentFile();
        if (directory != null && !directory.exists() && !directory.mkdirs()) {
            throw new IOException("Cannot create directory: " + directory.getAbsolutePath());
        }

        list.add(new PendingFile(sourceLocation, targetLocation));
        return sourceLocation.length;
    }
}

我刚刚写了所有这些,所以它可能不会立即工作,但我认为你应该能够让它与它一起工作。祝你好运!

于 2012-07-18T14:58:21.563 回答