当前位置: 首页 > 面试题库 >

Files.walk(),计算总大小

秋向阳
2023-03-14
问题内容

我正在尝试计算光盘上文件的大小。在Java的7本可以用做Files.walkFileTree如图我的答案在这里。

但是,如果我想使用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 避免这种异常?


问题答案:

不,无法避免此异常。

异常本身发生在的懒惰获取中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是绝对不可用的,因为您永远无法保证遍历目录时不会出现任何错误。

需要注意的重要一点是stacktrace包含sum()reduce()操作,这是因为路径是延迟加载的,所以在的点reduce(),调用了大多数流机制(在stacktrace中可见),然后获取路径,此时UnCheckedIOException发生。

如果让每个步行操作都在各自的线程上执行,则可能 被规避。但这不是您想做的事情。

另外,检查文件是否实际上可访问是 毫无价值的 (尽管在某种程度上很有用),因为您无法保证甚至在1毫秒后仍可读。

未来扩展

我相信它仍然可以修复,尽管我不知道它是如何FileVisitOption工作的。
当前有一个FileVisitOption.FOLLOW_LINKS,如果它基于每个文件运行,那么我怀疑FileVisitOption.IGNORE_ON_IOEXCEPTION也可以添加一个,但是我们无法在其中正确注入该功能。



 类似资料:
  • 问题内容: 我的表中的一列中包含大量BLOB数据。我正在编写一个实用程序以将数据转储到文件系统。但是在转储之前,我需要检查磁盘上是否有必要的空间来导出整个表中的所有Blob字段。 请提出一种有效的方法来获取表中所有Blob字段的大小。 问题答案: 您可以使用MySQL函数。有关更多详细信息,请参见此处。

  • 我试图在Acrobat中使用JavaScript以交互形式总计10个数据字段。最初,数据是手动输入的。我们创建的计算公式在手动输入数据时有效,但当数据从另一个表单导出,然后使用FDF文件导入到此表单时,计算公式不能正确合计。 当前工作流使用三种形式。数据输入表格1 打开表格3,将两个数据文件导入该表格。有两个具有类似公式的总计字段,一个将所有负数相加,另一个将所有正数相加。 但是,当我们导入两个文

  • 问题内容: 假设我有一个Java IntStream,是否可以将其转换为具有累积总和的IntStream?例如,以[4、2、6,…]开头的流应转换为[4、6、12,…]。 更笼统地说,应该如何实施有状态流操作?感觉这应该可行: 有一个明显的限制,即它仅适用于顺序流。但是,Stream.map明确需要无状态映射函数。我是否错过了Stream.statefulMap或Stream.cumulative

  • 问题内容: 我有这个MySQL查询: 返回如下内容: 我真正想要的是末尾的另一列显示运行总计: 这可能吗? 问题答案: 也许这对您来说是一个更简单的解决方案,并且可以防止数据库不得不执行大量查询。这仅执行一个查询,然后在一次通过中对结果进行一点数学运算。 这将为您提供一个额外的RT(运行总计)列。不要错过顶部的SET语句来首先初始化运行的total变量,否则您将只获得一列NULL值。

  • 问题内容: 我有这个MySQL查询: 返回如下内容: 我真正想要的是末尾的另一列以显示运行总计: 这可能吗? 问题答案: 也许对您来说是一个更简单的解决方案,并且可以防止数据库不得不执行大量查询。这仅执行一个查询,然后在一次通过中对结果进行一些数学运算。 这将为您提供一个额外的RT(运行总计)列。不要错过顶部的SET语句来首先初始化运行中的total变量,否则您将只获得一列NULL值。

  • 我想知道如何计算的累计总和在AnyLogic中。具体地说,我有一个循环事件,每周改变一个参数的值。从这个参数我想计算它收到的值的累计总和,我怎么做呢? 该事件是循环模式的超时。操作是: "name_parameter"=圆形(max(正常(10,200),0));