BufferedReader read(char[]) 如何工作?

How does a BufferedReader's read(char[]) work?

我在互联网上搜索时遇到了这段代码,可以从文件中读取文件并将其转换为字符串。但是我不明白 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){}
       }
   }
  1. 对象'in'有与文件相关的信息。
  2. 'arr'是长度等于文件内容长度的数组
  3. 然后 'in' 被读取到该文件长度

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

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

  • 已读取指定数量的字符,
  • 底层流的读取方法returns -1,表示end-of-file,或者
  • 基础流的就绪方法return为假,表明进一步的输入请求将被阻塞。

这里使用了第一个和第二个条件,希望第三个条件不要被踢进来,这样从本地文件读取就不会在任意文件位置造成“阻塞”。
File.length 告诉您文件的大小(以字节为单位)。文件中的字符数不能超过其字节数,这就是为什么 file.length 是您需要的字符数的一个很好的上限估计值。然而,由于存在可能导致单个字符存储为多个字节的编码(例如 UTF-8),您实际上应该使用该 read() 调用的 return 值,它告诉您读取的字符数,然后将其传递给 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 代码中获取它 - 在许多情况下这将是一个 File),使用它的 toPath()。如果您有一个 String,一个 Paths.get() 就可以减少打字。