Question

Having this kind of subdirectories:

C:\test\foo\a.dat (100kb)
C:\test\foo\b.dat (200kb)
C:\test\foo\another_dir\jim.dat (500kb)
C:\test\bar\ball.jpg (5kb)
C:\test\bar\sam\sam1.jpg (100kb)
C:\test\bar\sam\sam2.jpg (300kb)
C:\test\somefile.dat (700kb)

I want to get size of all subdirectories, but only show the top directory, Running the command java DU c:\test should produce the following output:

DIR C:\TEST\FOO 800KB
FILE C:\TEST\SOMEFILE.DAT 700KB
DIR C:\TEST\BAR 405KB

any help will be great, my code so far is close but not getting the expected output ? :/

import java.io.File;

public class DU {

public static void main(String[] args) {

    File file = new File(args[0]);

    if (file.isDirectory()) {
        File[] filesNames = file.listFiles();
        for (File temp : filesNames) {
            if (temp.isDirectory()) {
                File dirs = new File(temp.getPath());
                getDirSize(dirs);
            } else {
                System.out.println("FILE - " + temp.getPath() + " "
                        + friendlyFileSize(temp.length()));
            }
        }
    } else {
        System.out.println("THIS IS NOT A FILE LOCATION!");
    }
}   

private static long getDirSize(File dirs) {
    long size = 0;
    for (File file : dirs.listFiles()) {
        if (file.isFile())
            size += file.length();
        else
            size += getDirSize(file);
    }
    System.out.println("DIR - " + dirs+" "+ friendlyFileSize(size));
    return size;

}

public static String friendlyFileSize(long size) {
    String unit = "bytes";
    if (size > 1024) {
        size = size / 1024;
        unit = "kb";
    }
    if (size > 1024) {
        size = size / 1024;
        unit = "mb";
    }
    if (size > 1024) {
        size = size / 1024;
        unit = "gb";
    }
    return " (" + size + ")" + unit;
}
}

This code get the output of all subdirectories instead showing a total of all of them and printing just top directory ??? Many thx for any help :D

FILE - c:\test\baba.pdf  (4)mb
FILE - c:\test\babdb.txt  (67)kb
DIR - c:\test\one\oneone  (67)kb
DIR - c:\test\one  (814)kb
DIR - c:\test\two\twotwo  (322)kb
DIR - c:\test\two  (368)kb
Was it helpful?

Solution

Your recquirement is that input a folder then show the sizes of all files(file including folder) of the folder.
We define the size of a folder is the sum of the size of files in the folder(including sub-folder).

So, the process of the source code is below:
(1) list-up all files of the folder as input.
(2) calculate file-size of listing in (1).
(3) show file-type(FILE OR DIR), the paths of files listing in (1), and file-size calculated in (2).

the source code of (1) and (3) is below:

public static void showFileSizes(File dir) {
  File[] files = dir.listFiles(); // (1)
  long[] fileSizes = new long[files.length];
  for(int i = 0; i < files.length; i++) {
    fileSizes[i] = calculateFileSize(file[i]);//invoke the method corresponding to (2).
    boolean isDirectory = files[i].isDirectory();
    System.out.println(((isDirectory)?"DIR":"FILE") + " - " + files[i].getAbsolutePath() + friendlyFileSize(fileSizes[i]));// as (3)
  }
}

the source code of (2) is below:

public static long calculateFileSize(File file) {
  long fileSize = 0L;
  if(file.isDirectory()) {
     File[] children = file.listFiles();
     for(File child : children) {
       fileSize += calculateFileSize(child);
     }
  }
  else {
    fileSize = file.length();
  }
  return fileSize;
}

The only thing you have to do is invoke showFileSizes method.

OTHER TIPS

It is quite easy by using Java 7 new File I/O NIO.2 framework mostly by using Files.walkFileTree(Path, Set, int, FileVisitor) method.

import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
import java.util.concurrent.atomic.AtomicLong;

public class Main {

    private static class PrintFiles extends SimpleFileVisitor<Path> {

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
            if (attr.isDirectory()) {
                try {
                    System.out.format("Directory: %s, size: %d bytes\n", file, getDirSize(file));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else if (attr.isRegularFile()) {
                System.out.format("Regular file: %s, size %d bytes\n", file, attr.size());
            }
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) {
            System.err.println(exc);
            return FileVisitResult.CONTINUE;
        }

        /**
         * Walks through directory path and sums up all files' sizes.
         * 
         * @param dirPath Path to directory.
         * @return Total size of all files included in dirPath.
         * @throws IOException
         */
        private long getDirSize(Path dirPath) throws IOException {
            final AtomicLong size = new AtomicLong(0L);

            Files.walkFileTree(dirPath, 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 {
                   //just skip
                    return FileVisitResult.CONTINUE;
                }
            });

            return size.get();
        }
    }

    /**
     * Main method.
     * 
     * @param args
     */
    public static void main(String [] args) {
        Path p = Paths.get("d:\\octopress");
        try {
            Files.walkFileTree(p, EnumSet.noneOf(FileVisitOption.class), 1, new PrintFiles());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Keep it short and simple by using FileUtils.sizeOfDirectory(). You have to import org.apache.commons.io.FileUtils for this.

        if (temp.isDirectory()) {
            File dirs = new File(temp.getPath());

            System.out.println("DIR - " + dirs+" "+ friendlyFileSize(FileUtils.sizeOfDirectory(dirs)));

        }

Staying close to what you've already done, you would have to increment the directory size everytime you encounter it.

for (File temp : filesNames) {
                if (temp.isDirectory()) {
                    dirs = new File(temp.getPath());
                    heavy += getDirSize(dirs);
                } else {
                    System.out.println("FILE - " + temp.getPath() + " "
                            + friendlyFileSize(temp.length()));
                }
            }

You also would want to display the the size after summing it all up against the parent of the subdirectories

public static void main(String[] args) {
...
...
    System.out.println("DIR - " + dirs.getParent() + " "
                + friendlyFileSize(heavy));
    }

Also, you need to check for whether the directory has any files or not, else dirs.listFiles() would cause a NPE

private static long getDirSize(File dirs) {
        long size = 0;
        if (dirs != null && dirs.listFiles() != null) {
            for (File file : dirs.listFiles()) {
                if (file.isFile())
                    size += file.length();
                else
                    size += getDirSize(file);
            }
        }

        return size;

    }

Your whole code slightly modified:

public class SubDirs {
    static long heavy;

    public static void main(String[] args) {

        File file = new File("C:\\Program Files");
        File dirs = null;

        if (file.isDirectory()) {
            File[] filesNames = file.listFiles();
            for (File temp : filesNames) {
                if (temp.isDirectory()) {
                    dirs = new File(temp.getPath());
                    heavy += getDirSize(dirs);
                } else {
                    System.out.println("FILE - " + temp.getPath() + " "
                            + friendlyFileSize(temp.length()));
                }
            }
        } else {
            System.out.println("THIS IS NOT A FILE LOCATION!");
        }

        System.out.println("DIR - " + dirs.getParent() + " "
                + friendlyFileSize(heavy));
    }

    private static long getDirSize(File dirs) {
        long size = 0;
        if (dirs != null && dirs.listFiles() != null) {
            for (File file : dirs.listFiles()) {
                if (file.isFile())
                    size += file.length();
                else
                    size += getDirSize(file);
            }
        }

        return size;

    }

    public static String friendlyFileSize(long size) {
        String unit = "bytes";
        if (size > 1024) {
            size = size / 1024;
            unit = "kb";
        }
        if (size > 1024) {
            size = size / 1024;
            unit = "mb";
        }
        if (size > 1024) {
            size = size / 1024;
            unit = "gb";
        }
        return " (" + size + ")" + unit;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top