Reputation: 2086
What's the quickest, non-hack-involving way of determining the size of a (flat, non-nested) directory on Android? Getting a list of files with the File object and enumerating through them to compute the size is unbearably slow - surely there's a better way?
(I know that I can use threading to compute the size in the background, but that wouldn't be an ideal solution in this case)
Upvotes: 5
Views: 1575
Reputation: 7121
You can also use this method, similar to the other one proposed
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;
}
It returns size in kilobytes, or -1
if an error was encountered.
Upvotes: 2
Reputation: 2336
I don't know if this qualifies as a "non-hack" to you, but if you don't want to reinvent the wheel, you could just use the Linux command du
. Here's a clip from its manpage:
NAME
du - estimate file space usage
SYNOPSIS
du [OPTION]... [FILE]...
DESCRIPTION
Summarize disk usage of each FILE, recursively for directories.
In particular the parameters -c
and -s
should interest you:
$ du -sc /tmp
164 /tmp
164 total
$
The number it outputs is the total number of bytes in the directory. I don't know if you want your size in bytes or human-readable format, but -h
is there for you if you need that too.
You'll have to read the output from the command. Capturing command output has already been covered in this question, from which I'm going to borrow heavily to provide the following example:
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;
}
From there you would need to parse the output for the numerical value representing the total size, which I'm leaving out as it should be fairly trivial. Optionally, you could just throw that in the du()
function and make the function return an int
instead of a String
.
Upvotes: 1