gpt4 book ai didi

java - Files.walk(),计算总大小

转载 作者:行者123 更新时间:2023-11-29 08:50:01 24 4
gpt4 key购买 nike

我正在尝试计算光盘上文件的大小。在 java-7 中,这可以使用 Files.walkFileTree 来完成。如我的回答所示 here .

但是,如果我想使用 java-8 流来执行此操作,它将适用于某些文件夹,但不适用于所有文件夹。

public static void main(String[] args) throws IOException {
long size = Files.walk(Paths.get("c:/")).mapToLong(MyMain::count).sum();
System.out.println("size=" + size);
}

static long count(Path path) {
try {
return Files.size(path);
} catch (IOException | UncheckedIOException e) {
return 0;
}
}

上面的代码对于路径 a:/files/ 会很好地工作但是对于 c:/ 它会抛出下面的异常

Exception in thread "main" java.io.UncheckedIOException: java.nio.file.AccessDeniedException: c:\$Recycle.Bin\S-1-5-20
at java.nio.file.FileTreeIterator.fetchNextIfNeeded(Unknown Source)
at java.nio.file.FileTreeIterator.hasNext(Unknown Source)
at java.util.Iterator.forEachRemaining(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.LongPipeline.reduce(Unknown Source)
at java.util.stream.LongPipeline.sum(Unknown Source)
at MyMain.main(MyMain.java:16)

我了解它的来源以及如何使用 Files.walkFileTree API 避免它。

但是如何使用 Files.walk() 来避免这个异常呢? API?

最佳答案

不,这个异常(exception)是不可避免的。

异常本身发生在 Files.walk() 的延迟获取中,因此为什么您没有及早发现它以及为什么没有办法规避它,请考虑以下代码:

long size = Files.walk(Paths.get("C://"))
.peek(System.out::println)
.mapToLong(this::count)
.sum();

在我的系统上,这将在我的计算机上打印:

C:\
C:\$Recycle.Bin
Exception in thread "main" java.io.UncheckedIOException: java.nio.file.AccessDeniedException: C:\$Recycle.Bin\S-1-5-18

并且由于在第三个文件的(主)线程上抛出异常,该线程上的所有进一步执行都将停止。

我认为这是一个设计失败,因为就目前而言 Files.walk 是绝对不可用的,因为您永远无法保证遍历目录时不会出现错误。

需要注意的一个重点是堆栈跟踪包括一个sum()reduce() 操作,这是因为路径被延迟加载,所以在reduce() 点,大量的流机制被调用(在堆栈跟踪中可见),然后它获取路径,此时 UnCheckedIOException 发生。

如果您让每个行走操作都在它们自己的线程上执行,则可能可以绕过它。但无论如何,这不是您想要做的事情。

此外,检查文件是否实际可访问是毫无值(value)(尽管在某种程度上有用),因为您无法保证即使 1 毫秒后它也可读。

future 扩展

我相信它仍然可以修复,虽然我不知道 FileVisitOption 是如何工作的。
目前有一个 FileVisitOption.FOLLOW_LINKS,如果它在每个文件的基础上运行,那么我怀疑也可以添加一个 FileVisitOption.IGNORE_ON_IOEXCEPTION,但是我们无法正确注入(inject)那个功能在那里。

关于java - Files.walk(),计算总大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23220542/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com