什么是在Android上确定(扁平、非嵌套)目录大小的最快且不涉及黑客行为的方法?使用File对象获取文件列表并枚举它们以计算大小的速度非常慢——肯定有更好的方法吧?
(我知道我可以使用线程在后台计算大小,但在这种情况下这不是理想的解决方案)
(我知道我可以使用线程在后台计算大小,但在这种情况下这不是理想的解决方案)
public static long getDirSize(File dir) {
try {
Process du = Runtime.getRuntime().exec("/system/bin/du -sc " + dir.getCanonicalPath(), new String[]{}, Environment.getRootDirectory());
BufferedReader br = new BufferedReader(new InputStreamReader(du.getInputStream()));
String[] parts = br.readLine().split("\\s+");
return Long.parseLong(parts[0]);
} catch (IOException e) {
Log.w(TAG, "Could not find size of directory " + dir.getAbsolutePath(), e);
}
return -1;
}
该函数返回以千字节为单位的大小,如果遇到错误则返回-1
。
parts[0]
是一个 String
,像 1.9G
。所以我没有使用 Long.parseLong(parts[0])
,而是直接返回了 String
值。 - Joshua Pinter我不知道这是否符合你的“非黑客”标准,但如果你不想重复造轮子,可以使用Linux命令du
。下面是它的manpage摘录:
NAME
du - estimate file space usage
SYNOPSIS
du [OPTION]... [FILE]...
DESCRIPTION
Summarize disk usage of each FILE, recursively for directories.
-c
和-s
应该会引起您的兴趣:$ du -sc /tmp
164 /tmp
164 total
$
它输出的数字是目录中所有字节的总数。我不知道你想要以字节或人类可读格式显示大小,但如果需要,-h
也可以提供。
您将不得不阅读命令的输出。捕获命令输出已经在this question中讨论过,我将大量借用该问题来提供以下示例:
public String du(String fileName) {
Class<?> execClass = Class.forName("android.os.Exec");
Method createSubprocess = execClass.getMethod("createSubprocess", String.class, String.class, String.class, int[].class);
int[] pid = new int[1];
FileDescriptor fd = (FileDescriptor)createSubprocess.invoke(null, "/system/bin/du -sc", fileName, null, pid);
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fd)));
String output = "";
try {
String line;
while ((line = reader.readLine()) != null) {
output += line + "\n";
}
}
catch (IOException e) {}
return output;
}
从那里开始,您需要解析输出以获取表示总大小的数字值,我将其留空,因为它应该相当简单。可选地,您可以将其放入du()
函数中,并使函数返回一个int
而不是String
。
File
对象的大小会发生什么?我猜你只会得到FS条目的大小(可能是4 KB左右),但谁知道呢... - Vladislav Zorov