JAVA - 获取所有子目录的大小?

时间:2014-01-05 13:11:04

标签: java size directory subdirectory

拥有这种子目录:

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)

我想获取所有子目录的大小,但只显示顶级目录,运行命令java DU c:\ test应该产生以下输出:

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

任何帮助都会很棒,到目前为止,我的代码已接近但未达到预期的输出? :/

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;
}
}

此代码获取所有子目录的输出,而不是显示所有子目录的总和并打印只是顶级目录???许多thx任何帮助: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

4 个答案:

答案 0 :(得分:2)

您的要求是输入一个文件夹,然后显示该文件夹的所有文件(包括文件夹的文件)的大小 我们定义文件夹的大小是文件夹中文件大小的总和(包括子文件夹)。

因此,源代码的过程如下:
(1)列出文件夹的所有文件作为输入 (2)计算(1)中列出的文件大小 (3)显示文件类型(FILE或DIR),(1)中列出的文件路径和(2)中计算的文件大小。

(1)和(3)的源代码如下:

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)
  }
}

(2)的源代码如下:

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;
}

您唯一需要做的就是调用showFileSizes方法。

答案 1 :(得分:2)

使用Java 7新的File I / O NIO.2框架非常容易,主要是使用Files.walkFileTree(Path,Set,int,FileVisitor)方法。

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();
        }
    }
}

答案 2 :(得分:0)

与您已经完成的工作保持一致,每次遇到目录时都必须增加目录大小。

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()));
                }
            }

您还希望在将所有内容与子目录的父项相加后显示大小

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

此外,您需要检查目录是否包含任何文件,否则dirs.listFiles()将导致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;

    }

您的整个代码略有修改:

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;
    }
}

答案 3 :(得分:0)

使用FileUtils.sizeOfDirectory()保持简短。你必须为此导入org.apache.commons.io.FileUtils。

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

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

        }