2015-09-05 14 views
8

Đoạn mã sau đây đếm số lượng tập tin trong một thư mục:bỏ qua ngoại lệ và tiếp tục & đếm tập tin trong một thư mục

 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()); 
     } 

Đoạn mã trên không để có được số lượng file, nếu một ngoại lệ được ném .

Câu hỏi đặt ra là: Làm cách nào để bỏ qua ngoại lệ và tiếp tục đếm số lượng tệp.

Trong Java 7: Tôi đã sử dụng Files.walkFileTree(path, utils), với lớp sau:

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; 
    } 

} 

Edit: Đây là stack trace của ngoại lệ:

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 
+0

Dấu vết ngăn xếp của ngoại lệ là gì? –

+0

@JBNizet Tôi đã cập nhật câu hỏi bằng dấu vết ngăn xếp của ngoại lệ. – Kachna

+3

Với ngoại lệ, tôi không nghĩ bạn có thể làm bất cứ điều gì về nó. Tiếp tục sử dụng SimpleFileVisitor. –

Trả lời

2

Cho đến nay, có vẻ như Files.walk vẫn không hoạt động tốt với luồng. Thay vào đó, bạn có thể muốn sử dụng Files.newDirectoryStream để thay thế. Dưới đây là một số đoạn mã có thể hữu ích.

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); 
} 
Các vấn đề liên quan