10.2.3 Reading from a file
10.2.3 从文件中读取
When reading a file, the following steps are involved in the process:
读取文件时,该过程涉及以下步骤:
Open the file. 打开文件。
Read from the file. 从文件中读取。
Close the file. 关闭文件。
Unlike the writing phase, a file opened as read-only doesn't have much impact on a system if not closed. However, good programming practice mandates that all input sources should be properly closed to minimise any undesirable impacts on the system.
与写入阶段不同,如果未关闭,则以只读方式打开的文件不会对系统产生太大影响。但是,良好的编程实践要求所有 input source 都应正确关闭,以尽量减少对系统的任何不良影响。
Similar to writing, many of the steps above could potentially cause errors to happen in our program and as such we must ensure to include the code to properly handle the checked exceptions thrown when calling these methods using the library classes.
与编写类似,上述许多步骤可能会导致我们的程序中发生错误,因此我们必须确保包含代码,以正确处理使用库类调用这些方法时抛出的已检查异常。
FileReader class FileReader 类
For reading from a file, we only need to learn about one class: the FileReader class. While the FileReader class complements the FileWriter class we learned about earlier, it only has a method to read a single character at a time, rather than the whole line. This makes things difficult if we don't know in advance how many characters we need to read!
要从文件中读取数据,我们只需要了解一个类:FileReader 类。 虽然 FileReader 类补充了我们之前了解的 FileWriter 类,但它只有一个一次读取单个字符而不是整行的方法。如果我们事先不知道需要阅读多少个字符,这会让事情变得困难!
To solve this problem, when we are working with the FileReader class, we need to employ another class which can read inputs of arbitrary length. There are two different classes we can use for this purpose: BufferedReader and Scanner. Since we're already familiar with the Scanner class, this is the one we will use. Let's explore some code for reading from a file.
为了解决这个问题,当我们使用 FileReader 类时,我们需要使用另一个可以读取任意长度输入的类。为此,我们可以使用两个不同的类:BufferedReader 和 Scanner。由于我们已经熟悉 Scanner 类,因此我们将使用该类。让我们探索一些用于从文件中读取的代码。
Our Ed platform doesn't allow us to have any persistent data within the lesson environment. As such, before reading the file we will be creating a text file first, so we can read from it.
我们的 Ed 平台不允许我们在课程环境中拥有任何持久数据。因此,在读取文件之前,我们将首先创建一个文本文件,以便我们可以从中读取。
Note the following: 请注意以下事项:
Line 48, which creates the object of the FileReader class, MUST appear inside a try block as it throws a checked exception, which must be handled.
第 48 行(创建 FileReader 类的对象)必须出现在 try 块中,因为它会引发必须处理的已检查异常。Line 69 closes the file. It is good programming practice to close all files even if opening in read-only mode.
第 69 行关闭文件。即使以只读模式打开,也要关闭所有文件,这是一种很好的编程习惯。Line 51 declares a second object of the Scanner class. It is very important to note the argument passed when calling the non-default constructor. The argument is no longer System.in (implying keyboard), but it uses the object of the FileReader class instead.
第 51 行声明了 Scanner 类的第二个对象。注意调用非默认构造函数时传递的参数非常重要。该参数不再 System.in(表示键盘),而是改用 FileReader 类的对象。Line 52 controls the iteration by using the method hasNextLine() from the Scanner class, which returns true if there is more data on the file to be read.
第 52 行使用 Scanner 类中的方法 hasNextLine() 控制迭代,如果文件中有更多要读取的数据,则返回 true。We can read data from the file the same way we read it from the keyboard when using the Scanner class. However, the same limitations that apply to reading from the keyboard also apply to reading from the file. Hence the dummy nextLine() method on Line 57 since the previous method call was nextInt().
我们可以像使用 Scanner 类时从键盘读取数据一样从文件中读取数据。但是,适用于从键盘读取的相同限制也适用于从文件中读取。因此,第 57 行上的虚拟 nextLine() 方法,因为上一个方法调用是 nextInt()。
For brevity, the above code doesn't show validation of the input data from the file. However, it is always good defensive programming to perform basic validations on the data to prevent the program from crashing due to badly formatted input data.
为简洁起见,上面的代码没有显示对文件中输入数据的验证。但是,对数据执行基本验证以防止程序由于输入数据格式错误而崩溃始终是很好的防御性编程。
The above is a simple approach to reading data from a text file, which should allow new programmers to be able to perform basic operations with character-based files. As always, there are advantages and limitations that we need to address based on the requirements within the program specification.
以上是从文本文件中读取数据的简单方法,它应该允许新程序员能够使用基于字符的文件执行基本操作。与往常一样,我们需要根据程序规范中的要求解决一些优点和限制。