使用Java

时间:2018-01-05 21:26:05

标签: java file-io

我想使用此代码只读取文件中的第一行:

String line = Files.lines(path).findFirst().get();

我认为这不会将整个文件的内容加载到内存中。相反,它打开文件,只读取第一行,然后关闭文件。

我的假设是否正确?

2 个答案:

答案 0 :(得分:6)

来自Files Javadoc

  

静态流线(路径路径) - 从文件中读取所有行作为   流。

Files.lines(path)读取所有行,这意味着它们有可能被访问,但加载到内存中的内容取决于流所需的内容。在您的情况下,只会访问第一行(存储在内存中),因为BufferedReader可以根据需要懒惰地将内容加载到内存中。

答案 1 :(得分:5)

Files#lines方法使用BufferedReader类来使用BufferedReader#lines访问这些行。来自source

  

返回一个Stream,其元素是从中读取的行   BufferedReader中。 java.util.stream.Stream是懒惰填充的,即,   只读在终端流操作期间发生。读者必须   在终端流的执行期间不操作   操作。否则,终端流操作的结果是   未定义。

     

执行终端流操作后没有   保证读者将处于特定的位置   阅读下一个字符或行。

     

如果在访问底层证书时抛出IOException   BufferedReader,它包含在一个UncheckedIOException中   从Stream方法抛出,导致读取发生。这个   如果在BufferedReader上调用,则该方法将返回Stream   关闭。该流上的任何操作都需要从中读取   BufferedReader在关闭后会导致UncheckedIOException   被抛出。

public Stream<String> lines() {
    Iterator<String> iter = new Iterator<String>() {
        String nextLine = null;

        @Override
        public boolean hasNext() {
            if (nextLine != null) {
                return true;
            } else {
                try {
                    nextLine = readLine();
                    return (nextLine != null);
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            }
        }

        @Override
        public String next() {
            if (nextLine != null || hasNext()) {
                String line = nextLine;
                nextLine = null;
                return line;
            } else {
                throw new NoSuchElementException();
            }
        }
    };
    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
            iter, Spliterator.ORDERED | Spliterator.NONNULL), false);
}

Stream创建的StreamSupport.streamIterator支持。只询问一个元素,因为您调用了Stream#findFirst。因此,只需拨打hasNextnext一次,这意味着BufferedReader#readLine只会被调用一次。