【问题标题】:JAVA - get size of all subdirectories?JAVA - 获取所有子目录的大小?
【发布时间】:2014-01-22 21:50:56
【问题描述】:

有这种子目录:

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

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

【问题讨论】:

  • 只需将你的 sop 从 getDirSize 移到 main 方法

标签: java size directory subdirectory


【解决方案1】:

保持接近您已经完成的内容,每次遇到它时都必须增加目录大小。

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

【讨论】:

    【解决方案2】:

    使用 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)));
    
            }
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        所以,源代码的过程如下:
        (1) 列出文件夹的所有文件作为输入。
        (2) 计算 (1) 中列表的文件大小。
        (3) 显示文件类型(FILE OR 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 方法。

        【讨论】:

        • 谢谢,这正是我所需要的,也很好,清晰的解释!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-04
        • 2017-05-30
        • 2020-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多