赞
踩
先说结论:
如果要读取一个大文件(文件大小超过了内存大小),则可以考虑使用java.nio.file.Files.lines方法来读取这个大型文件的内容。
关于java.nio.file.Files类中lines方法的说明:
jdk1.8.0_311中原码部分:
- /**
- * Read all lines from a file as a {@code Stream}. Unlike {@link
- * #readAllLines(Path, Charset) readAllLines}, this method does not read
- * all lines into a {@code List}, but instead populates lazily as the stream
- * is consumed.
- *
- * <p> Bytes from the file are decoded into characters using the specified
- * charset and the same line terminators as specified by {@code
- * readAllLines} are supported.
- *
- * <p> After this method returns, then any subsequent I/O exception that
- * occurs while reading from the file or when a malformed or unmappable byte
- * sequence is read, is wrapped in an {@link UncheckedIOException} that will
- * be thrown from the
- * {@link java.util.stream.Stream} method that caused the read to take
- * place. In case an {@code IOException} is thrown when closing the file,
- * it is also wrapped as an {@code UncheckedIOException}.
- *
- * <p> The returned stream encapsulates a {@link Reader}. If timely
- * disposal of file system resources is required, the try-with-resources
- * construct should be used to ensure that the stream's
- * {@link Stream#close close} method is invoked after the stream operations
- * are completed.
- *
- *
- * @param path
- * the path to the file
- * @param cs
- * the charset to use for decoding
- *
- * @return the lines from the file as a {@code Stream}
- *
- * @throws IOException
- * if an I/O error occurs opening the file
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkRead(String) checkRead}
- * method is invoked to check read access to the file.
- *
- * @see #readAllLines(Path, Charset)
- * @see #newBufferedReader(Path, Charset)
- * @see java.io.BufferedReader#lines()
- * @since 1.8
- */
- public static Stream<String> lines(Path path, Charset cs) throws IOException {
- BufferedReader br = Files.newBufferedReader(path, cs);
- try {
- return br.lines().onClose(asUncheckedRunnable(br));
- } catch (Error|RuntimeException e) {
- try {
- br.close();
- } catch (IOException ex) {
- try {
- e.addSuppressed(ex);
- } catch (Throwable ignore) {}
- }
- throw e;
- }
- }
-
- /**
- * Read all lines from a file as a {@code Stream}. Bytes from the file are
- * decoded into characters using the {@link StandardCharsets#UTF_8 UTF-8}
- * {@link Charset charset}.
- *
- * <p> This method works as if invoking it were equivalent to evaluating the
- * expression:
- * <pre>{@code
- * Files.lines(path, StandardCharsets.UTF_8)
- * }</pre>
- *
- * @param path
- * the path to the file
- *
- * @return the lines from the file as a {@code Stream}
- *
- * @throws IOException
- * if an I/O error occurs opening the file
- * @throws SecurityException
- * In the case of the default provider, and a security manager is
- * installed, the {@link SecurityManager#checkRead(String) checkRead}
- * method is invoked to check read access to the file.
- *
- * @since 1.8
- */
- public static Stream<String> lines(Path path) throws IOException {
- return lines(path, StandardCharsets.UTF_8);
- }
从javadoc注解中可以看出,它将文件中的所有行作为 Stream 读取,与 readAllLines 不同,此方法不会将所有行读入 List 中(不全部加载到内存中),而是在流被使用时延迟填充(populates lazily)。
java.nio.file.Files
类中的 lines
方法是 Java 8 引入的一个非常有用的方法,用于处理文件和目录的 I/O 操作,它提供了一种流式(Stream-based)的方式来读取文件内容,并将文件的每一行作为字符串(String
)对象进行处理。
lines(Path path)方法使用默认字符集(通常是 UTF-8)来解码文件中的字节。
使用场景:
lines
方法可以方便地按行处理文件内容。lines
方法返回的 Stream 对象与其他 Stream 操作(如 map
、filter
、reduce
等)结合使用。lines
方法可以方便地读取日志文件并按行进行处理。lines
方法可以提供一个高效且简洁的解决方案。优缺点:
优点
lines
方法更加简洁和直观。lines
方法使用懒加载(lazy loading)方式读取文件内容,这意味着它不会一次性加载整个文件到内存中,从而减少了内存使用。缺点
lines
方法默认使用系统默认字符集来解码文件内容。如果文件使用了非默认字符集(如 ISO-8859-1),则需要手动指定字符集,否则可能会出现乱码问题。BufferedReader
或 Scanner
相比,lines
方法在处理文件读取错误时可能不太直观。你需要使用 try-catch 块来捕获和处理可能发生的 IOException
。lines
方法在大多数情况下都足够高效,但在处理大文件时,由于它使用 Stream API,可能会增加一些额外的开销。此外,如果你需要多次读取同一文件或进行大量的小文件读取操作,使用传统的文件读取方式可能会更加高效。示例代码:
- import java.io.IOException;
- import java.nio.charset.StandardCharsets;
- import java.nio.file.Files;
- import java.nio.file.Paths;
- import java.util.stream.Stream;
-
- public class FilesTest {
- public static void main(String[] args) {
- String filePath = "page\example.txt";
- // 使用默认字符编码读取文件的每一行
- try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
- lines.forEach(System.out::println);
- } catch (IOException e) {
- e.printStackTrace();
-
- }
- // 使用指定的字符编码读取文件的每一行
- try (Stream<String> lines = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8)) {
- lines.forEach(System.out::println);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- }
所以,如果之后遇到需要读取大型文件的内容进行处理又担心内存不足问题时,可以考虑使用Files.lines方法来进行处理哦~~~,它是在jdk1.8中引入的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。