Android - 复制文件(全部同时)

时间:2012-07-18 14:16:52

标签: android

我目前正在研究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));

1 个答案:

答案 0 :(得分: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;
    }
}

我刚才写了所有这些,所以它可能不会立即起作用,但我认为你应该能够使用它。古德勒克!