Get File Size in Java: Files.size(), Folder Size, KB and MB

Get the file size in Java with Files.size(), compute a directory size with Files.walk(), convert bytes to KB, MB and GB, and check free disk space.

Directory tree with file sizes being summed by Files.walk while a symbolic link and subfolders are skipped

To get the file size in Java, we call Files.size(path), which returns the length of the file in bytes as a long and throws NoSuchFileException when the file does not exist. For a directory, Java has no single call, so we add up the sizes of all files inside it.

We check file sizes to reject uploads above a limit, to show a download size in a UI, to rotate a log file once it grows past 10 MB, and to compute how much storage each user of a document app takes.

The following example reads the size of a log file, converts it to kilobytes and formats it for a user.

Path log = Files.writeString(Files.createTempFile("app", ".log"), "x".repeat(2560));
long bytes = Files.size(log);                                             // 2560
long legacyBytes = log.toFile().length();                                 // 2560
double kb = bytes / 1024.0;                                               // 2.5
String label = String.format(Locale.ROOT, "%.1f KB", kb);                 // "2.5 KB"

Notice that both Files.size() and the older File.length() return bytes, and any unit conversion is our job. We cover how the two methods differ for missing files, compute directory sizes with Files.walk() and Files.walkFileTree(), use Commons IO, format sizes as KB, MB and GB, and look at size on disk and free disk space.

1. Getting the File Size with Files.size()

The method Files.size(Path) reads the size from the file system metadata, so it does not open or read the file. It follows symbolic links and reports the size of the target file. For anything other than a regular file, such as a directory, the result is not specified, and on Linux it is often 4096, the size of the directory entry table, not of its contents.

An upload endpoint in a document app accepts files up to 5 MB. Checking the size of the stored temporary file before parsing it keeps a 2 GB upload from filling the memory of the parser.

static void checkUploadSize(Path upload, long maxBytes) throws IOException {
    long size = Files.size(upload);
    if (size > maxBytes) {
        throw new IllegalArgumentException("File too large: " + size + " bytes");
    }
}
long fiveMb = 5L * 1024 * 1024;
Path small = Files.write(Files.createTempFile("cv", ".pdf"), new byte[300_000]);
Path big = Files.write(Files.createTempFile("video", ".mp4"), new byte[6_000_000]);
checkUploadSize(small, fiveMb);
checkUploadSize(big, fiveMb);                                             // IllegalArgumentException: File too large: 6000000 bytes
long missing = Files.size(small.resolveSibling("deleted.pdf"));           // NoSuchFileException

The size of a symbolic link itself, rather than its target, comes from the attributes with LinkOption.NOFOLLOW_LINKS, as in Files.readAttributes(link, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS).size().

2. Check File Size using File.length()

The File.length() method of java.io.File also returns the size in bytes. The difference shows up when something goes wrong, because length() never throws an IOException. It returns 0L for a missing file and for a file it cannot read, which is the same value as for an empty file.

File empty = Files.createTempFile("empty", ".txt").toFile();
File gone = new File(empty.getParentFile(), "no-such-file.txt");
long emptyLength = empty.length();                                        // 0
long goneLength = gone.length();                                          // 0
long goneSize = Files.size(gone.toPath());                                // NoSuchFileException

A size check that sees 0 from File.length() cannot tell an empty file from a missing one, so new code uses Files.size(). When a library hands us a File, we call toPath() on it first. For a directory, length() also returns an unspecified value.

3. Calculating the Size of a Directory

A directory’s size is the sum of the sizes of the regular files in it and in all of its subfolders. We walk the tree, keep only regular files and add their sizes. The walk does not follow symbolic links by default, so a link that points back to a parent folder cannot cause an endless loop, and the contents of a linked folder are not counted. A link to a single file still passes Files::isRegularFile, which follows links, so its target’s size is added unless we filter with Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS).

Directory tree with file sizes being summed by Files.walk while a symbolic link and subfolders are skipped
A directory size is the sum of its regular files, and Files.walk() visits every level without descending into linked folders

A document app that enforces a 1 GB quota per user computes the size of each user’s folder this way. The lambda in mapToLong() cannot throw IOException, so a small helper wraps Files.size() and rethrows any failure as UncheckedIOException.

static long sizeOf(Path file) {
    try {
        return Files.size(file);
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}
static long directorySize(Path dir) throws IOException {
    try (Stream<Path> paths = Files.walk(dir)) {
        return paths.filter(Files::isRegularFile)
                .mapToLong(p -> sizeOf(p))
                .sum();
    }
}
Path user = Files.createTempDirectory("user-docs");
Files.write(user.resolve("cv.pdf"), new byte[1500]);
Path photos = Files.createDirectories(user.resolve("photos/2026"));
Files.write(photos.resolve("beach.jpg"), new byte[4000]);
Files.write(photos.resolve("city.jpg"), new byte[2500]);
long used = directorySize(user);                                          // 8000

The stream version stops at the first folder it cannot read, because Files.walk() throws UncheckedIOException with an AccessDeniedException inside. When a total of everything readable is good enough, such as for a disk usage report, Files.walkFileTree() lets us skip failures. It also hands us the attributes of each file, so we read attrs.size() without a second call to the file system.

static long readableSize(Path dir) throws IOException {
    AtomicLong total = new AtomicLong();
    Files.walkFileTree(dir, new SimpleFileVisitor<>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
            if (attrs.isRegularFile()) {
                total.addAndGet(attrs.size());
            }
            return FileVisitResult.CONTINUE;
        }
        @Override
        public FileVisitResult visitFileFailed(Path file, IOException e) {
            return FileVisitResult.CONTINUE;
        }
    });
    return total.get();
}
Path shared = Files.createTempDirectory("shared");
Files.write(shared.resolve("a.txt"), new byte[700]);
Files.createDirectories(shared.resolve("old"));
Files.write(shared.resolve("old/b.txt"), new byte[300]);
long readable = readableSize(shared);                                     // 1000

Two details affect the total. A file with several hard links is counted once per link, and the result is the logical size of the files, not the disk space they take, which section 6 explains. Listing the largest files of a folder works with the same walk, and the list all files article shows more walking options.

4. Check File Size using Commons IO’s FileUtils.sizeOf()

Apache Commons IO has FileUtils.sizeOf(File), which returns the size of a file or, for a directory, the recursive total. The method sizeOfDirectory() accepts only directories, and PathUtils.sizeOfDirectory() takes a Path.

Path team = Files.createTempDirectory("team");
Files.write(team.resolve("plan.pdf"), new byte[1500]);
Files.createDirectories(team.resolve("drafts"));
Files.write(team.resolve("drafts/v1.pdf"), new byte[500]);
long commonsFile = FileUtils.sizeOf(team.resolve("plan.pdf").toFile());   // 1500
long commonsDir = FileUtils.sizeOfDirectory(team.toFile());               // 2000
long pathDir = PathUtils.sizeOfDirectory(team);                           // 2000

Like Files.walk(), Commons IO does not follow symbolic links inside the directory, but it adds the few bytes of each link entry itself to the total. The variants sizeOfAsBigInteger() and sizeOfDirectoryAsBigInteger() exist for totals above Long.MAX_VALUE bytes, which is about 9.2 exabytes, so a long is enough for any real disk. The library is useful when the project already uses it, and the JDK version from section 3 needs no dependency.

5. Displaying Formatted Output of File Size

Users read sizes as KB, MB or GB, not as 2333444 bytes. Operating systems disagree on the units. Windows shows 1 KB as 1024 bytes, while macOS and many storage vendors use 1000 bytes, and the IEC names KiB, MiB and GiB mark the 1024-based units without ambiguity.

5.1. Converting Bytes to KB, MB and GB

Dividing by a double keeps the fraction, and String.format() rounds it for display. Integer division with bytes / 1024 cuts the fraction off, so a 1,500-byte file shows as 1 KB.

long size = 2_333_444L;
double sizeKb = size / 1024.0;                                            // 2278.75390625
double sizeMb = size / (1024.0 * 1024);                                   // 2.2253456115722656
String mb = String.format(Locale.ROOT, "%.2f MB", sizeMb);                // "2.23 MB"
String grouped = String.format(Locale.ROOT, "%,d bytes", size);           // "2,333,444 bytes"

5.2. A Human-Readable Size Method

A file manager or a download page picks the unit for us. The method below finds the largest 1024-based unit that fits, using the position of the highest set bit, and prints one decimal place.

static String humanReadable(long bytes) {
    if (bytes < 1024) {
        return bytes + " B";
    }
    int unit = (63 - Long.numberOfLeadingZeros(bytes)) / 10;
    double value = (double) bytes / (1L << (unit * 10));
    return String.format(Locale.ROOT, "%.1f %cB", value, "KMGTPE".charAt(unit - 1));
}
String tiny = humanReadable(512);                                        // "512 B"
String photo = humanReadable(2_333_444);                                  // "2.2 MB"
String movie = humanReadable(4_700_000_000L);                             // "4.4 GB"

5.3. Using FileUtils.byteCountToDisplaySize()

Commons IO has byteCountToDisplaySize() for the same job. It uses 1024-based units and rounds down to a whole number, so 2,333,444 bytes, which are 2.23 MB, show as “2 MB”, and 1,536 bytes show as “1 KB”.

String commonsMb = FileUtils.byteCountToDisplaySize(2_333_444L);          // "2 MB"
String commonsGb = FileUtils.byteCountToDisplaySize(2_333_444_555L);      // "2 GB"
String commonsKb = FileUtils.byteCountToDisplaySize(1536);                // "1 KB"

6. Size on Disk and Free Disk Space

The value from Files.size() is the logical size, the number of bytes we can read from the file. The space the file takes on disk can be larger, because the file system allocates whole blocks, or much smaller for compressed and sparse files. A sparse file has holes that take no disk space. Setting the length of a new file to 10 MB without writing any data creates such a file.

Path sparse = Files.createTempFile("disk", ".img");
try (RandomAccessFile raf = new RandomAccessFile(sparse.toFile(), "rw")) {
    raf.setLength(10L * 1024 * 1024);
}
long logical = Files.size(sparse);                                        // 10485760

The JDK has no portable method for the allocated size, which is what du on Linux or the “Size on disk” field on Windows shows. What Java does offer is the free space of a disk, through FileStore. An export job that writes a 4 GB archive checks getUsableSpace() first and fails early with a clear message, instead of failing halfway with a full disk.

Path exportDir = Files.createTempDirectory("export");
FileStore store = Files.getFileStore(exportDir);
long usable = store.getUsableSpace();                                     // free bytes for this JVM
long totalSpace = store.getTotalSpace();                                  // size of the partition
boolean fits = usable > 4L * 1024 * 1024 * 1024;                          // true when 4 GB fit

7. File Size in Java FAQs

Megabyte conversion, a zero from File.length(), empty files, speed and directories account for most file size questions.

7.1. How do we get the file size in MB in Java?

Divide the result of Files.size() by 1024.0 * 1024 and format it, as in String.format(“%.2f MB”, Files.size(path) / (1024.0 * 1024)). Use 1_000_000.0 instead when the UI follows the decimal units of macOS or storage vendors.

7.2. Why does File.length() return 0?

Either the file is empty, it does not exist, or the JVM cannot read its metadata. The method returns 0L in all three cases. Files.size() throws NoSuchFileException or AccessDeniedException instead, so we know which case we hit.

7.3. How do we check whether a file is empty?

Compare Files.size(path) with 0. For a directory, emptiness means no entries, which the check if a directory is empty article covers.

7.4. Is Files.size() faster than reading the file?

Yes. It reads only the file system metadata and never opens the file, so a 10 GB file costs the same as a 10-byte file. Reading all bytes with Files.readAllBytes() to count them loads the whole file into memory.

7.5. Does Files.size() work for a directory?

No. The method returns a number, but the value is not specified and does not include the files inside. We sum the files with the walk from section 3.

8. Conclusion

The Files.size() method returns a file’s size in bytes from its metadata and throws a clear exception for a missing file, while File.length() returns 0 for errors without reporting them. A directory size is the sum of its regular files, computed with Files.walk() or, when unreadable folders must be skipped, with Files.walkFileTree().

For display, we divide by 1024, format with String.format() or a small helper, and remember that byteCountToDisplaySize() rounds down. The logical size can differ from the space on disk, and FileStore.getUsableSpace() tells us whether a large file will fit. The Java IO tutorial groups the other file tasks.

9. References

Happy Learning !!

Source Code on Github

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.