使用Scanner和BufferedReader读取文本文件
使用PrintWriter写入文本文件请参考:https://blog.csdn.net/qq_43524683/article/details/99689599
使用DataInputStream和DataOutputStream读写二进制文件请参考:https://blog.csdn.net/qq_43524683/article/details/100544798
首先创建一个文本文件data.txt,放入如下内容。
之后放到指定路径,这里使用绝对路径。
To see the world in a grain of sand,
a heaven in a wild flower;
Hold infinity in the palm of your hand,
and eternity in an hour.
1. 主函数
public static void main(String[] args){
Demo demo=new Demo();
demo.useScanner(); //使用Scanner读取文本文件
demo.useBufferReader(); //使用BufferedReader读取文本文件
}
主函数中将这两种方法分别封装在两个方法中,可分别注释用来检验结果。
2. 使用Scanner读取文本文件
public void useScanner(){
String fileName="F:\\IDEA_Codes\\ReadTextFiles\\src\\data.txt"; //绝对路径
Scanner fromFile=null;
System.out.println("The file "+fileName+" contains the following lines:");
try{
fromFile=new Scanner(new File(fileName));
} catch (FileNotFoundException e) {
//e.printStackTrace();
System.out.println("Error opening the file "+fileName);
System.exit(0);
}
while (fromFile.hasNextLine()){ //使用hasNextLine来防止nextLine读取超出文件末尾。
String line=fromFile.nextLine(); //若超出文件末尾,将抛出NoSuchElementException(运行时异常)
System.out.println(line);
}
fromFile.close();
}
Scanner没有以文件名为参数的构造函数,但是,Scanner可以接收一个File对象作为参数。File是 一个类,以与系统无关的方式表示文件。其构造雨数可以有一个作为其参数的文件名字符串。由于Scanner的构造函数可以抛出一个FileNotFoundException,因此在try代码块中调用它。
while循环使用Scanner的hasNextLine和nextLine方法来读取文本文件中的数据行。在本示例中只是简单地显示这些行。当到达文件末尾时hasNextLine返回false,循环结束。此时将关闭文件。注意hasNextLine、nextLine和close方法不会抛出检验异常,因此它们没有位于try代码块中。
3. 使用BufferedReader读取文本文件
public void useBufferReader(){
String fileName="F:\\IDEA_Codes\\ReadTextFiles\\src\\data.txt"; //绝对路径
BufferedReader fromFile=null;
try{
FileReader fileReader=new FileReader(fileName); //可以抛出FileNotFoundException异常
fromFile=new BufferedReader(fileReader);
System.out.println("The file "+fileName+" contains the following lines:");
String line=fromFile.readLine(); //可以抛出IOException异常
while (line!=null){
System.out.println(line);
line=fromFile.readLine(); //可以抛出IOException异常
}
} catch (FileNotFoundException e) {
//e.printStackTrace();
System.out.println("Error opening the file "+fileName);
System.exit(0);
} catch (IOException e) {
//e.printStackTrace();
System.out.println("Error opening the file "+fileName);
}
finally { //使用try-catch方法指导为什么发生IOException异常
try{
if(fromFile!=null)
fromFile.close(); //关闭
} catch (IOException e) {
//e.printStackTrace();
System.out.println("Error opening the file "+fileName);
System.exit(0);
}
}
}
与类Scanner 一样,类BufferedReader没有以文件名作为参数的构造函数,所以需要使用另一个类(在此的FileReader类),帮助打开文件。FileReader 的构造函数将接收一个文件名作为它的参数,并产生一个数据流,该数据流可以作为BufferedReader的构造雨数的参数。使用这两个类,就可以有适合的构造丽数和使用的方法。
类BufferedRcader的方法readLine 从输人数据流读取下一行输人并返回此行。如果读取超出文件末尾,则返回null。 注意readLine从文本文件读取一行。而Scanner的nextLine方法如果读取超出了文件末尾,则抛出一个运行时异常。
注意,上述代码中捕获两种类型的异常, FileNotFoundException与IOException。 打开文件可能抛出FileNotFoundException,而对readLine( )的任何调用可能抛出IOException,因为FileNotFoundException是IOException的一种,所以也可以选择只捕获IOException。不过,如果这样做的话,就不能识别异常的原因了。究竟引起异常的原因是打开文件,还是在它打开之后从文件读入?
完成读取文本文件后,要调用close方法来关闭该文件,就像写人文件完成后要关闭文件一样。但是,这里是在try代码块中调用close 方法,因为BufferedReader的close 方法可能抛出IOException异常。由于readLine 也会抛出异常,因此,close有自己的try代码块和catch代码块,这样就知道为什么发生IOException异常。这里我们把try代码块及其相应的catch代码块放在与第一个 try 代码块关联的finally代码块中。这样,即使是在读取文件时发生了异常也可以关闭该文件。
注:如果把数据流A传递给数据流B的构造函数,那么关闭数据流B的同时也将关闭数据流A。因此,在前面的示例中,关闭数据流fromFile也就关闭了数据。
在主函数中分别注意检验即可。
总体来说使用Scanner读取文本文件要比用BufferedReader更容易,而且,Scanner具有比BufferedReader更多的方法。