java读取文件内容-java 按二进制读取文件
在上一篇文章中,我介绍了“创建文件和写入文件数据的5种方式”,本节我们将介绍从文件中读取数据的6种方式。
另外,为了方便大家理解java读取文件内容,我为这篇文章录制了对应的视频:总结java从文件中读取数据的6种方法-JAVA IO基础总结Part 2
流式数据处理,按行读取
可以说每一种方法都有其适用的场景,下面我们将一一介绍。
1.扫描仪
第一个方法是Scanner,它是JDK1.5以后提供的一个API。 其特点是按行、按分隔符读取文件数据。 可以读取String类型、Int类型、Long类型等底层数据类型的数据。
@Test
void testReadFile1() throws IOException {
//文件内容:Hello World|Hello Zimug
String fileName = "D:\data\test\newFile4.txt";
try (Scanner sc = new Scanner(new FileReader(fileName))) {
while (sc.hasNextLine()) { //按行读取字符串
String line = sc.nextLine();
System.out.println(line);
}
}
try (Scanner sc = new Scanner(new FileReader(fileName))) {
sc.useDelimiter("\|"); //分隔符
while (sc.hasNext()) { //按分隔符读取字符串
String str = sc.next();
System.out.println(str);
}
}
//sc.hasNextInt() 、hasNextFloat() 、基础数据类型等等等等。
//文件内容:1|2
fileName = "D:\data\test\newFile5.txt";
try (Scanner sc = new Scanner(new FileReader(fileName))) {
sc.useDelimiter("\|"); //分隔符
while (sc.hasNextInt()) { //按分隔符读取Int
int intValue = sc.nextInt();
System.out.println(intValue);
}
}
}
上述方法的输出如下:
Hello World|Hello Zimug
Hello World
Hello Zimug
1
2
复制
2. 文件。 行(Java
如果需要对数据文件的内容进行逐行处理,这种方法是我推荐大家使用的一种方法。 代码简单,利用java 8的stream将文件读取和文件处理有机结合。
@Test
void testReadFile2() throws IOException {
String fileName = "D:\data\test\newFile.txt";
// 读取文件内容到Stream流中,按行读取
Stream lines = Files.lines(Paths.get(fileName));
// 随机行顺序进行数据处理
lines.forEach(ele -> {
System.out.println(ele);
});
}
复制
forEach不保证行数据在Stream流中的顺序,但是速度很快。 如果想按顺序处理文件中的行数据,可以使用forEachOrdered,但是处理效率会降低。
// 按文件行顺序进行处理
lines.forEachOrdered(System.out::println);
复制
或者利用CPU的多重求和能力进行数据并行处理parallel(),适合比较大的文件。
// 按文件行顺序进行处理
lines.parallel().forEachOrdered(System.out::println);
复制
您也可以将 Stream 转换为 List,但请注意,这意味着您必须一次将所有数据加载到内存中,并注意 java.lang.OutOfMemoryError
// 转换成List, 要注意java.lang.OutOfMemoryError: Java heap space
List collect = lines.collect(Collectors.toList());
复制
3. 文件。 读取所有行
这个方法还是java8提供的。 如果我们不需要Stream,想直接逐行读取文件得到一个Listjava读取文件内容,使用下面的方法。 同样的问题:这意味着你必须一次将所有数据加载到内存中,当心 java.lang.OutOfMemoryError
@Test
void testReadFile3() throws IOException {
String fileName = "D:\data\test\newFile3.txt";
// 转换成List, 要注意java.lang.OutOfMemoryError: Java heap space
List lines = Files.readAllLines(Paths.get(fileName),
StandardCharsets.UTF_8);
lines.forEach(System.out::println);
}
复制
4. 文件。 读取字符串(JDK 11)
从java11开始,它为我们提供了一次读取一个文件的方法。 文件不能超过2G,注意你的服务器和JVM内存。 这种方法适用于快速读取小文本文件。
@Test
void testReadFile4() throws IOException {
String fileName = "D:\data\test\newFile3.txt";
// java 11 开始提供的方法,读取文件不能超过2G,与你的内存息息相关
//String s = Files.readString(Paths.get(fileName));
}
复制
5. 文件。 读取所有字节()
没有JDK11(readAllBytes()从JDK7开始),还想快速读取一个文件的内容,一次性转成String怎么办? 先将数据读取为二进制数组,然后将其转换为String内容。 这种方法适合在没有JDK11的情况下快速读取小文本文件。
@Test
void testReadFile5() throws IOException {
String fileName = "D:\data\test\newFile3.txt";
//如果是JDK11用上面的方法,如果不是用这个方法也很容易
byte[] bytes = Files.readAllBytes(Paths.get(fileName));
String content = new String(bytes, StandardCharsets.UTF_8);
System.out.println(content);
}
复制
6.经典流水线的方式
最后一种是管道流的经典方式
@Test
void testReadFile6() throws IOException {
String fileName = "D:\data\test\newFile3.txt";
// 带缓冲的流读取,默认缓冲区8k
try (BufferedReader br = new BufferedReader(new FileReader(fileName))){
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
//java 8中这样写也可以
try (BufferedReader br = Files.newBufferedReader(Paths.get(fileName))){
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
复制
这种方法可以通过流水线的嵌套来组合使用,更加灵活。 比如我们要从文件中读取java Object,可以使用下面的代码,前提是文件中的数据是用ObjectOutputStream写的,可以用ObjectInputStream读取。
try (FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis)){
ois.readObject();
}
复制