当前位置: 主页 > JAVA语言

java读取文件内容-java 按二进制读取文件

发布时间:2023-02-13 07:07   浏览次数:次   作者:佚名

在上一篇文章中,我介绍了“创建文件和写入文件数据的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();
} 

复制