首页 > 解决方案 > BufferedReader 的 read(char[]) 是如何工作的?

问题描述

我在互联网上搜索并遇到此代码以从文件中读取文件并将其转换为字符串。但我不明白如何in.read(arr)一次读取文件的所有内容。

   import java.util.Scanner;
   import java.io.*;
   class Main{
       public static void main(String[] args)
       {
         Scanner sc = new Scanner(System.in);
         String s = sc.next();
         try
         {
           File file = new File(s);
           BufferedReader in = new BufferedReader(new FileReader(file));
           int c;
           char arr[] = new char[(int)file.length()];
           in.read(arr);
           String res = new String(arr);
           System.out.println(res);
         }
         catch(Exception e){}
       }
   }

标签: javaarraysfilebufferedreaderfile-handling

解决方案


在当代 Java 代码中,您将Files.readString用于此目的。它是在 Java 11 中引入的,它专门将整个文本文件读入String.

您询问的代码中发生的事情与read(someArray)方法很常见:它们读取了许多条件,例如

  • 已读取指定数量的字符,
  • 底层流的read方法返回-1,表示文件结束,或者
  • 底层流的 ready 方法返回 false,表示进一步的输入请求会阻塞。

在这里您使用第一个和第二个条件,并希望第三个不会启动,因此从本地文件读取不会导致在任意文件位置“阻塞”。
File.length告诉您文件的大小(以字节为单位)。文件中的字符数不能超过其大小(以字节为单位),这就是为什么file.length对您需要的字符数有一个很好的估计值。但是,由于某些编码可能导致单个字符存储为多个字节(例如 UTF-8),因此您实际上应该使用该read()调用的返回值,该值告诉您读取的字符数,然后将其传递给String构造函数:

char arr[] = new char[(int)file.length()];
int count = in.read(arr);
String res = new String(arr, 0, count);

您的代码的实际变体:

  • File.toPath()如果你喜欢

    import java.util.Scanner;
    import java.io.File;
    import java.nio.file.Files; // "Files" is needed of course
    
    class Main
    {
        public static void main(String[] args)
        {
            Scanner sc = new Scanner(System.in);
            String s = sc.next();
            try
            {
                File file = new File(s);
                String res = Files.readString(file.toPath()); // many lines disappeared
                System.out.println(res);
            }
            catch (Exception e) {}
        }
    }
    
  • java.nio和接口:

    import java.util.Scanner;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    class Main
    {
        public static void main(String[] args)
        {
            Scanner sc = new Scanner(System.in);
            String s = sc.next();
            try
            {
                Path path = Paths.get(s); // "File file" became "Path path"
                String res = Files.readString(path); // many lines disappeared again
                System.out.println(res);
            }
            catch (Exception e) {}
        }
    }
    

这取决于你的品味和你已经拥有的东西。如果您仍然有一个File对象(例如您需要它的大小用于其他目的,或者您从 GUI 代码中获取它 - 在许多情况下这将是 a File),请使用它的toPath(). 如果你有一个String,一个单一Paths.get()的打字少。


推荐阅读