我目前正在研究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));
答案 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;
}
}
我刚才写了所有这些,所以它可能不会立即起作用,但我认为你应该能够使用它。古德勒克!