获取文件夹或文件的大小

如何检索Java中的文件夹或文件的大小?

java.io.File file = new java.io.File("myfile.txt"); file.length(); 

这将返回文件的长度,如果文件不存在,则返回0 。 没有内置的方法来获取文件夹的大小,您将不得不recursion地使用目录树(使用表示目录的文件对象的listFiles()方法)并累积目录大小:

 public static long folderSize(File directory) { long length = 0; for (File file : directory.listFiles()) { if (file.isFile()) length += file.length(); else length += folderSize(file); } return length; } 

警告 :这种方法不适合生产使用。 directory.listFiles()可能返回null并导致NullPointerException 。 此外,它不考虑符号链接,并可能有其他失败模式。 使用这种方法 。

您需要commons-io的 FileUtils#sizeOfDirectory(File)

请注意,您将需要手动检查该文件是否为目录,因为如果非目录传递给该方法,该方法将引发exception。

警告 :这个方法(从commons-io 2.4开始)有一个bug,如果目录被同时修改,可能会抛出IllegalArgumentException

使用java-7 nio api,计算文件夹的大小可以做得更快。

这里是一个可以运行的强壮的例子,不会抛出exception。 它将logging无法进入的目录或遇到问题遍历。 符号链接被忽略,并且目录的并发修改不会导致比必要的更多的麻烦。

 /** * Attempts to calculate the size of a file or directory. * * <p> * Since the operation is non-atomic, the returned value may be inaccurate. * However, this method is quick and does its best. */ public static long size(Path path) { final AtomicLong size = new AtomicLong(0); try { Files.walkFileTree(path, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { size.addAndGet(attrs.size()); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) { System.out.println("skipped: " + file + " (" + exc + ")"); // Skip folders that can't be traversed return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) { if (exc != null) System.out.println("had trouble traversing: " + dir + " (" + exc + ")"); // Ignore errors traversing a folder return FileVisitResult.CONTINUE; } }); } catch (IOException e) { throw new AssertionError("walkFileTree will not throw IOException if the FileVisitor does not"); } return size.get(); } 
 public static long getFolderSize(File dir) { long size = 0; for (File file : dir.listFiles()) { if (file.isFile()) { System.out.println(file.getName() + " " + file.length()); size += file.length(); } else size += getFolderSize(file); } return size; } 

在Java 8中:

 long size = Files.walk(path).mapToLong( p -> p.toFile().length() ).sum(); 

在映射步骤中使用Files::size会更好,但会引发检查exception。

更新:
您还应该知道,如果某些文件/文件夹不可访问,这可能会引发exception。 看到这个问题和另一个解决scheme使用番石榴 。

File.length() ( Javadoc )。

请注意,这不适用于目录,或不能保证工作。

对于一个目录,你想要什么? 如果它是它下面的所有文件的总大小,您可以使用File.isDirectory()File.isDirectory()recursion地走孩子, File.isDirectory()它们的大小进行求和。

File对象有一个length方法:

 f = new File("your/file/name"); f.length(); 

下面是获取一般文件大小(适用于目录和非目录)的最佳方法:

 public static long getSize(File file) { long size; if (file.isDirectory()) { size = 0; for (File child : file.listFiles()) { size += getSize(child); } } else { size = file.length(); } return size; } 

编辑:请注意,这可能是一个耗时的操作。 不要在UI线程上运行它。

另外,在这里(取自https://stackoverflow.com/a/5599842/1696171 )是从长返回一个用户可读的string的一个不错的方法:

 public static String getReadableSize(long size) { if(size <= 0) return "0"; final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" }; int digitGroups = (int) (Math.log10(size)/Math.log10(1024)); return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups)) + " " + units[digitGroups]; } 

对于Java 8来说,这是一个正确的方法:

 Files.walk(new File("D:/temp").toPath()) .map(f -> f.toFile()) .filter(f -> f.isFile()) .mapToLong(f -> f.length()).sum() 

过滤掉所有的目录是很重要的 ,因为目录的长度方法不能保证为0。

至less这个代码提供了像Windows资源pipe理器本身一样的大小信息。

如果您想使用Java 8 NIO API,以下程序将打印它所在目录的大小(以字节为单位)。

 import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class PathSize { public static void main(String[] args) { Path path = Paths.get("."); long size = calculateSize(path); System.out.println(size); } /** * Returns the size, in bytes, of the specified <tt>path</tt>. If the given * path is a regular file, trivially its size is returned. Else the path is * a directory and its contents are recursively explored, returning the * total sum of all files within the directory. * <p> * If an I/O exception occurs, it is suppressed within this method and * <tt>0</tt> is returned as the size of the specified <tt>path</tt>. * * @param path path whose size is to be returned * @return size of the specified path */ public static long calculateSize(Path path) { try { if (Files.isRegularFile(path)) { return Files.size(path); } return Files.list(path).mapToLong(PathSize::calculateSize).sum(); } catch (IOException e) { return 0L; } } } 

calculateSize方法对于Path对象是通用的,所以它也适用于文件。 请注意 ,如果文件或目录不可访问,则在此情况下,path对象的返回大小将为0

 public long folderSize (String directory) { File curDir = new File(directory); long length = 0; for(File f : curDir.listFiles()) { if(f.isDirectory()) { for ( File child : f.listFiles()) { length = length + child.length(); } System.out.println("Directory: " + f.getName() + " " + length + "kb"); } else { length = f.length(); System.out.println("File: " + f.getName() + " " + length + "kb"); } length = 0; } return length; } 

经过大量的研究,并在StackOverflow中提出了不同的解决scheme。 我终于决定写我自己的解决scheme。 我的目的是有没有抛出机制,因为我不想崩溃,如果API无法获取文件夹大小。 这种方法不适用于multithreading场景。

首先,我想在遍历文件系统树时检查有效的目录。

 private static boolean isValidDir(File dir){ if (dir != null && dir.exists() && dir.isDirectory()){ return true; }else{ return false; } } 

第二我不希望我的recursion调用进入符号链接(软链接),并包括在总的聚合大小。

 public static boolean isSymlink(File file) throws IOException { File canon; if (file.getParent() == null) { canon = file; } else { canon = new File(file.getParentFile().getCanonicalFile(), file.getName()); } return !canon.getCanonicalFile().equals(canon.getAbsoluteFile()); } 

最后是基于recursion的实现来获取指定目录的大小。 注意dir.listFiles()的空检查。 根据javadoc有可能这个方法可以返回null。

 public static long getDirSize(File dir){ if (!isValidDir(dir)) return 0L; File[] files = dir.listFiles(); //Guard for null pointer exception on files if (files == null){ return 0L; }else{ long size = 0L; for(File file : files){ if (file.isFile()){ size += file.length(); }else{ try{ if (!isSymlink(file)) size += getDirSize(file); }catch (IOException ioe){ //digest exception } } } return size; } } 

一些奶油蛋糕,API获取列表文件的大小(可能是根目录下的所有文件和文件夹)。

 public static long getDirSize(List<File> files){ long size = 0L; for(File file : files){ if (file.isDirectory()){ size += getDirSize(file); } else { size += file.length(); } } return size; } 

在Linux中,如果你想sorting目录然后du -hs * | sorting-h

  • 适用于AndroidJava
  • 适用于文件夹和文件
  • 在需要的地方检查空指针
  • 忽略符号链接 aka快捷方式
  • 生产准备!

源代码:

  public long fileSize(File root) { if(root == null){ return 0; } if(root.isFile()){ return root.length(); } try { if(isSymlink(root)){ return 0; } } catch (IOException e) { e.printStackTrace(); return 0; } long length = 0; File[] files = root.listFiles(); if(files == null){ return 0; } for (File file : files) { length += fileSize(file); } return length; } private static boolean isSymlink(File file) throws IOException { File canon; if (file.getParent() == null) { canon = file; } else { File canonDir = file.getParentFile().getCanonicalFile(); canon = new File(canonDir, file.getName()); } return !canon.getCanonicalFile().equals(canon.getAbsoluteFile()); }