忽略异常并继续&计算目录中的文件 [英] ignore exception and continue & counting files in a directory
问题描述
以下代码片段计算目录中的文件数:
The following snippet of code counts the number of files in a directory:
Path path = ...;
....
long count = 0;
try {
count = Files.walk(path).parallel().filter(p -> !Files.isDirectory(p)).count();
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
如果抛出异常,上面的代码无法获取文件数。
The code above fails to get the number of files, if an exception is thrown.
问题是:如何忽略异常并继续计算文件数。
The question is: How do I ignore the exception and continue counting the number of files.
在Java 7中:我使用 Files.walkFileTree(path,utils)
,使用以下类:
In Java 7: I have used Files.walkFileTree(path, utils)
, with the following class:
public class Utils extends SimpleFileVisitor<Path> {
private long count;
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (attrs.isRegularFile()) {
count++;
}
return CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
System.err.println(file.getFileName());
return CONTINUE;
}
public long countFilesInDirectoryJava7() {
return count;
}
}
编辑:以下是异常的堆栈跟踪:
Here is the stack trace of the exception:
Exception in thread "main" java.io.UncheckedIOException: java.nio.file.AccessDeniedException: E:\8431c36f5b6a3d7169de9cc70a\1025
at java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:88)
at java.nio.file.FileTreeIterator.hasNext(FileTreeIterator.java:104)
at java.util.Spliterators$IteratorSpliterator.trySplit(Spliterators.java:1784)
at java.util.stream.AbstractTask.compute(AbstractTask.java:297)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:401)
at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734)
at java.util.stream.ReduceOps$ReduceOp.evaluateParallel(ReduceOps.java:714)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.util.stream.LongPipeline.reduce(LongPipeline.java:438)
at java.util.stream.LongPipeline.sum(LongPipeline.java:396)
at Utils.countFilesInDirectoryJava8(Utils.java:47)
at TestPath.main(TestPath.java:27)
Caused by: java.nio.file.AccessDeniedException: E:\8431c36f5b6a3d7169de9cc70a\1025
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsDirectoryStream.<init>(WindowsDirectoryStream.java:86)
at sun.nio.fs.WindowsFileSystemProvider.newDirectoryStream(WindowsFileSystemProvider.java:518)
at java.nio.file.Files.newDirectoryStream(Files.java:457)
at java.nio.file.FileTreeWalker.visit(FileTreeWalker.java:300)
at java.nio.file.FileTreeWalker.next(FileTreeWalker.java:372)
at java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:84)
... 13 more
Java Result: 1
推荐答案
到目前为止,似乎 Files.walk
仍然不能很好地使用流。相反,您可能希望使用 Files.newDirectoryStream
。这里有一些可能有帮助的代码片段。
So far, it seems Files.walk
still does not play well with streams. Instead, you might want to use Files.newDirectoryStream
instead. Here's some code snippet that might help.
static class FN<T extends Path> implements Function<T, Stream<T>> {
@Override
public Stream<T> apply(T p) {
if (!Files.isDirectory(p, LinkOption.NOFOLLOW_LINKS)) {
return Stream.of(p);
} else {
try {
return toStream(Files.newDirectoryStream(p)).flatMap(q -> apply((T) q));
} catch (IOException ex) {
return Stream.empty();
}
}
}
}
public static void main(String[] args) throws IOException {
Path path = Paths.get("some path");
long count = toStream(Files.newDirectoryStream(path))
.parallel()
.flatMap(new FN<>()::apply)
.count();
System.out.println("count: " + count);
}
static <T> Stream<T> toStream(Iterable<T> iterable) {
return StreamSupport.stream(iterable.spliterator(), false);
}
这篇关于忽略异常并继续&计算目录中的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!