Java 读取文件
在 Java 中有多种读取文件内容的方式。
Files.readAllLines
读取文件到 List(Java 8)Files.readAllBytes
读取文件到byte\[]
数组(Java 8)Files.lines
读取文件内容到Stream
流 (Java 8 )Files.readString
读取文件到字符串(Java 11),
按行读取文件( Java 1.1 +)BufferedInputStream
按字节读取文件(Java 1.0 +)Scanner
读取文件(Java 1.5+,很少用)
文件读取操作需要注意关闭输入流,自 Java 7 开始,可以通过 try-with-resource
方式自动关闭流。详情可以参考:Try-with-resource
读取文件还需要注意文件大小,如果文件过大,一次性读取到内存中,可能会发生内存溢出。
本文读取示例文件:
➜ pwd
/Users/darcy/wdbyte
➜ cat log.txt
111 hello
222 www
333 wdbyte
444 com
Files.readAllLines ⭐️
Java 7 新增了 Files
类,Java 8 增加了 readAllLines
方法,可以直接读取文件内容到 List<String
。
Path path = Paths.get("/Users/darcy/wdbyte/log.txt");
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
for (String line : lines) {
System.out.println(line);
}
运行结果:
111 hello
222 www
333 wdbyte
444 com
Files.readAllBytes ⭐️
使用 Files.readAllBytes
可以读取文件内容到字节数组。
Path path = Paths.get("/Users/darcy/wdbyte/log.txt");
byte[] bytes = Files.readAllBytes(path);
String content = new String(bytes, StandardCharsets.UTF_8);
System.out.println(content);
Files.lines ⭐️
Java 新增了 Files.line
可以读取文件为 Stream
流,然后可以按行读取。注意 stream 流需要关闭,下面的示例中通过 try 方式自动关闭。
Path path = Paths.get("/Users/darcy/wdbyte/log.txt");
try (Stream<String> stream = Files.lines(path);) {
stream.forEach(System.out::println);
}
对于大文件,也可以使用 parallel
并行流读取,遍历时可以使用 forEachOrdered
保证顺序。
try (Stream<String> stream = Files.lines(path);) {
stream.parallel().forEachOrdered(System.out::println);
}
Files.readString
Java 11 开始,增加了 Files.readString
可以直接读取文件内容为一个字符串。但是要求文件内容大小不能超过 2G。
Path path = Paths.get("/Users/darcy/wdbyte/log.txt");
String content = Files.readString(path, StandardCharsets.UTF_8);
System.out.println(content);
运行输出:
111 hello
222 www
333 wdbyte
444 com
BufferedReader
BufferedReader
是自 Java 1.1 就存在的文件读取方式,很多新方法也是它的再次封装。
File file = new File("/Users/darcy/wdbyte/log.txt");
String line;
// 默认读取缓冲区大小 8K
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
运行输出:
111 hello
222 www
333 wdbyte
444 com
BufferedReader
可以设置缓冲区大小,提高缓冲区大小,可以在读取大文件时提高速度。
// 定义缓冲区大小为 128 K
int buffer = 128 * 1024;
try (BufferedReader br = new BufferedReader(new FileReader(file), buffer)) {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
从 Java 8 开始,可以直接通过 Files
类构造 BufferedReader
。
Path path = Paths.get("/Users/darcy/wdbyte/log.txt");
String line;
try (BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8);) {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
BufferedInputStream
自 Java 1.0 就存在的读取方式,可以按字节读取文件内容。
File file = new File("/Users/darcy/wdbyte/log.txt");
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);) {
StringBuilder content = new StringBuilder();
int data;
while ((data = bis.read()) != -1) {
content.append((char)data);
}
System.out.println(content.toString());
} catch (IOException e) {
e.printStackTrace();
}
Scanner
Scanner
读取文件,很少使用。
File file = new File("/Users/darcy/wdbyte/log.txt");
try (Scanner sc = new Scanner(new FileReader(file))) {
while (sc.hasNextLine()) {
String line = sc.nextLine();
System.out.println(line);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
Apache Commons IO
引入依赖:
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.1</version>
</dependency>
读取文件所有内容。
public void readFileByApacheCommons() throws IOException {
File file = new File("/Users/darcy/wdbyte/test.txt");
List<String> list = FileUtils.readLines(file, StandardCharsets.UTF_8);
for (String data : list) {
System.out.println(data);
}
}
一如既往,文章中代码存放在 Github.com/niumoo/javaNotes.