声纳扫描说 Use try-with-resources or close this "Stream" in a "finally" clause

Sonar scan says Use try-with-resources or close this "Stream" in a "finally" clause

Sonar qube 出现以下错误:

Use try-with-resources or close this "Stream" in a "finally" clause

这是我的代码:

Path start = Paths.get(filePath);
Stream<File> stream;
try {
    stream = Files.walk(start, 1, FileVisitOption.FOLLOW_LINKS).map(s -> s.toFile());
    List<File> files = stream.collect(Collectors.toList());
                    files.remove(0);
                    for (File f : files) {
                        String fileName = f.toPath().getFileName().toString();
                        if (fileName.matches(regex)) {
                            fileList.add(f.toPath().toString());
                        }
                    }
    } catch (IOException e) {
}

我该如何解决这个错误?

以这种方式定义和打开您的流:

try (Stream<File> stream = Files.walk(start, 1, FileVisitOption.FOLLOW_LINKS).map(s -> s.toFile())){

这样做,系统会自动关闭流,您无需担心

关闭流以防它在打开流时抛出异常。

  public static void main(String[] args) {
    Path start = Paths.get("");
    Stream<File> stream = null;
    List<String> fileList = new ArrayList<>();
    try {
        stream = Files.walk(start, 1, FileVisitOption.FOLLOW_LINKS).map(s -> s.toFile());
        List<File> files = stream.collect(Collectors.toList());
        files.remove(0);
        for (File f : files) {
            String fileName = f.toPath().getFileName().toString();
            if (fileName.matches("")) {
                fileList.add(f.toPath().toString());
            }
        }
    } catch (IOException e) {
    // Do something
    }finally {
        if(stream!=null)
            stream.close();
    }
}

从 Ryan 所说的扩展,我更愿意将要关闭的流的范围保持尽可能小:

try (Stream<File> stream = Files.walk(start, 1, FileVisitOption.FOLLOW_LINKS)) {
    List<File> files = stream
            .map(s -> s.toFile())
            .collect(Collectors.toList());
}

就是说,您流式传输、收集到一个列表,然后循环播放更多内容。可以改进的地方:

try (Stream<File> stream = Files.walk(start, 1, FileVisitOption.FOLLOW_LINKS)) {
    stream
            .skip(1) // replacement of files.remove(0)
            // leave out converting to File
            .filter(f -> f.getFileName().toString().matches(regex)) // filter in the stream
            .map(Path::toString)
            .forEach(fileList::add);
}

我不太喜欢那个 fileList::add,所以如果您可以收集到 List<String> 并将其分配给 fileList,那将是首选。或者可能收集到 List<String> 然后使用 fileList.addAll.