How can I get the size of a file or directory using the new NIO in java 7?
-
What's wrong with the old way? Unless there is support for recursive directory size now. Is there? – Thilo Aug 31 '11 at 10:23
-
i've heard it is a lot faster. and i want to try that. – clamp Aug 31 '11 at 10:32
-
I have to wonder how it can be faster.. – Thilo Aug 31 '11 at 10:35
-
i think its because the check if a java.io.File is a directory or not is very slow. – clamp Aug 31 '11 at 10:37
-
@clamp: and **why** do you think that that's the case? – Joachim Sauer Aug 31 '11 at 10:43
-
for example here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6483858 and here: http://stackoverflow.com/questions/354703/is-there-a-workaround-for-javas-poor-performance-on-walking-huge-directories – clamp Aug 31 '11 at 10:53
-
@clamp: at least the second item can *indeed* be solved by using `Path`: since it returns an `Iterator`, it doesn't need to have resolved all members of the directory at the time the `iterator()` call returns and thus can "stream" the directory content, which more closely aligns with the native APIs on most OSes. – Joachim Sauer Aug 31 '11 at 11:24
3 Answers
Use Files.size(Path)
to get the size of a file.
For the size of a directory (meaning the size of all files contained in it), you still need to recurse manually, as far as I know.

- 302,674
- 57
- 556
- 614
-
-
2@Damodar: my answer contains a link to the JavaDoc. Why do you think that it's not present? – Joachim Sauer Aug 31 '11 at 10:28
-
2
-
thanks, then my next question would be, how would i recurse into a path's childpaths? – clamp Aug 31 '11 at 10:37
-
2@clamp: a `Path` *is* an `Iterable
`, so you can just do `for (Path child : parent) { /* do stuff */ }`. – Joachim Sauer Aug 31 '11 at 10:38
Here is a ready to run example that will also skip-and-log directories it can't enter. It uses java.util.concurrent.atomic.AtomicLong
to accumulate state.
public static void main(String[] args) throws IOException {
Path path = Paths.get("c:/");
long size = getSize(path);
System.out.println("size=" + size);
}
static long getSize(Path startPath) throws IOException {
final AtomicLong size = new AtomicLong(0);
Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
size.addAndGet(attrs.size());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc)
throws IOException {
// Skip folders that can't be traversed
System.out.println("skipped: " + file + "e=" + exc);
return FileVisitResult.CONTINUE;
}
});
return size.get();
}

- 11,367
- 5
- 53
- 74
-
1Wondering why the `AtomicLong` is necessary? Why not just a `long` ? Is there something parallel about [walkFileTree](http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#walkFileTree%28java.nio.file.Path,%20java.util.Set,%20int,%20java.nio.file.FileVisitor%29) ? – peterh Jan 21 '14 at 09:25
-
tbh, i just rewrote the other answer without using 3pp (MutableLong). But I think the variable has to be "final" to be accessed from the inner anonymous class. Which AtomicLong allows. – Aksel Willgert Jan 21 '14 at 11:42
-
1The method `postVisitDirectory`may be also overriden. It's not required to mark the `size` reference as final here because it isn't changed in the inner anonymous class. Only its content (value) is changed. A long array (with one single element) can be used in place of AtomicLong. – Stephan Sep 16 '17 at 08:36
MutableLong size = new MutableLong();
Files.walkFileTree(directoryPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
size.add(attrs.size());
}
}
This would calculate the size of all files in a directory. However, note that all files in the directory need to be regular files, as API specifies size method of BasicFileAttributes:
"The size of files that are not regular files is implementation specific and therefore unspecified."
If you stumble to unregulated file, you ll have either to not include it size, or return some unknown size. You can check if file is regular with
BasicFileAttributes.isRegularFile()

- 539
- 8
- 13
-
Nice answer, and for anyone wondering the Mutable* classes for primitives are part of apache.commons.lang – Nicholi Oct 01 '12 at 22:16