使用 Java 7 新 IO 获取文件/目录大小

Posted

技术标签:

【中文标题】使用 Java 7 新 IO 获取文件/目录大小【英文标题】:Get file/directory size using Java 7 new IO 【发布时间】:2011-11-07 12:12:07 【问题描述】:

如何使用 java 7 中的新 NIO 获取文件或目录的大小?

【问题讨论】:

老方法有什么问题?除非现在支持递归目录大小。有吗? 我听说它要快得多。我想试试。 我想知道它怎么能更快.. 我认为这是因为检查 java.io.File 是否是目录非常慢。 @clamp:为什么你认为是这样吗? 【参考方案1】:

使用Files.size(Path) 获取文件的大小。

对于一个目录的大小(即其中包含的所有文件的大小),据我所知,您仍然需要手动递归。

【讨论】:

我认为Java7 I/O中没有上述方法,请检查一次 @Damodar:我的回答包含指向 JavaDoc 的链接。为什么你认为它不存在? 他链接到 Oracle 的官方 API 文档。方法就在那里。 谢谢,那么我的下一个问题是,我将如何递归到路径的子路径? @clamp: 一个Path 一个Iterable<Path>,所以你可以做for (Path child : parent) /* do stuff */ 【参考方案2】:
MutableLong size = new MutableLong();
Files.walkFileTree(directoryPath, new SimpleFileVisitor<Path>() 
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException 
                size.add(attrs.size());
            

这将计算目录中所有文件的大小。但是请注意,目录中的所有文件都需要是常规文件,因为 API 指定了 BasicFileAttributes 的 size 方法:

“非常规文件的大小是特定于实现的,因此未指定。”

如果你偶然发现不受管制的文件,你要么不包括它的大小,要么返回一些未知的大小。您可以使用

检查文件是否正常
BasicFileAttributes.isRegularFile()

【讨论】:

不错的答案,对于任何想知道基元的 Mutable* 类是 apache.commons.lang 的一部分的人【参考方案3】:

这是一个准备运行的示例,它还将跳过并记录它无法进入的目录。它使用java.util.concurrent.atomic.AtomicLong 来累积状态。

public static void main(String[] args) throws IOException 
    Path path = Paths.get("c:/");
    long size = getSize(path);
    System.out.println("size=" + size);


static long getSize(Path startPath) throws IOException 
    final AtomicLong size = new AtomicLong(0);

    Files.walkFileTree(startPath, 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 
            // Skip folders that can't be traversed
            System.out.println("skipped: " + file + "e=" + exc);
            return FileVisitResult.CONTINUE;
        
    );

    return size.get();

【讨论】:

想知道为什么AtomicLong 是必要的吗?为什么不只是一个 long ? walkFileTree 有什么相似之处吗? tbh,我只是在不使用 3pp (MutableLong) 的情况下重写了另一个答案。但我认为变量必须是“最终的”才能从内部匿名类访问。 AtomicLong 允许。 方法postVisitDirectory也可能被覆盖。这里不需要将size 引用标记为final,因为它在内部匿名类中没有更改。仅更改其内容(值)。可以使用长数组(只有一个元素)来代替 AtomicLong。

以上是关于使用 Java 7 新 IO 获取文件/目录大小的主要内容,如果未能解决你的问题,请参考以下文章

Java IO流File类的使用

java IO:File类

IO流

java.io.file对象中获取文件长度时 调用length方法 返回的是文件占用空间大小.如何获取文件自身的大小呢?

Java.io.File

Thinking in java Chapter18 IO