Java文件读写
总的来说对文件进行操作需要三步:
- 打开一个文件,当文件打开时程序将会创建一个程序和文件之间的联系(File类)。
- 找到开始读写的位置,对文件进行操作(读取 / 写入…)
- 当程序使用完文件后,关闭文件
输入/输出流:
- 字节流:字节流处理单元为1个byte,操作byte类型和byte类型的数据,以byte数组为主。(图片,音乐等文件,字节流操作时不会用到缓存区(内存),而对文件直接进行操作)
- 字符流:程序中一个字符等于两个字节,字符流操作2个字节的Unicode字符。(文本文件)
本文中主要介绍对文本文件(字符流)进行操作
File类
在整个io包内唯一和文件本身有关的类,File对象就可以理解为文件本身。把文件作为参数传递给File类的构造器,对File对象进行的操作就等价为对文件进行的操作。
实例化一个File对象:
File file = new File(“./test.txt") //实例化File类时,必须设置好路径
File类的方法:
public boolean createNewFile() throws IOException //创建新文件
public boolean delete() //删除文件
public boolean exists() //判断文件是否存在
eg:判断文件是否存在
//使用File类的exists方法判断Number.txt时候存在:
File file = new File("Numbers.txt");
if (!file.exists()) {
System.out.println("The file Numbers.txt is not found.");
System.exit(0);
}
抛出异常
当程序运行时出现一些意料之外的情况时,我们就称之为程序抛出了一个异常(比如使用一个PrintWriter类进行写入文件,但是PrintWriter类的构造器却发现硬盘已经满了)
当程序抛出一个异常时,这个方法一定会通过另一种方式来解决或者继续抛出至上一层,当main方法抛出异常时,程序就会出现一条错误信息。因为PrintWriter类对象有可能抛出异常。我们先不讨论如何通过另一种方式来解决,而直接把异常直接抛出至上一层。
我们可以使用throws语句把所有异常不加处理直接抛出,throws后面的异常必须是可能被抛出的那一类异常(比如PrintWriter抛出IOException异常):
public static void main(String[] args) throws IOException
任何使用了PrintWriter类对象的方法都应该抛出IOException异常。比如你创建了一个叫buildFile的方法使用了PrintWriter类,然后在main方法中调用了buildFile方法,那么在buildFile和PrintWriter方法头后面都应该抛出IOException异常。
文件的写入
FileWriter类:
String str = "Hello World!";
File file = new File("./test.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fileWritter = new FileWriter(file.getName(), true);
fileWritter.write(str);
fileWritter.close();
为什么需要 close():因为计算机在内存中读取数据的速度远大于在磁盘中读取文件的速度,所以文件被打开时系统会在内存中创建许多缓存。当程序写入数据到文件中时,其实数据时首先被写入到缓存中,然后当缓存存储满后再写入到文件中。close()方法就是将缓存中还未保存的数据写入到文件中,当close()方法执行后,程序和文件的连接也会被切断。
BufferWriter类(对FileReader进行了包装,效率更高):
String str = "Hello World!";
File file = new File("./test.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file, true);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(str);
bufferedWriter.flush();
bufferedWriter.close();
flush():清空缓冲区数据
PrintWriter类(类似于FileReader类):
Scanner keyboard = new Scanner(System.in);
String filename;
filename = keyboard.nextLine;
PrintWriter outputFile = new PrintWriter(filename); //如果文件已经存在,那原同名文件将会被抹除,并重新创建一个文件。
outputFile.println("Simon");
outputFile.print("John ");
outputFile.println("Rick");
outputFile.print("David");
outputFile.close();
//在一个文件里添加数据:
FileWriter fwriter = new FileWriter("MyFriends.txt", true);
PrintWriter outputFile = new PrintWriter(fwriter);
FileWriter对象会建立程序与MyFriends.txt的连接,任何被写入的数据都会写入到原文件的后面(而不是抹除原文件而建立一个新的同名文件),如果原文件不存在则会创建一个新文件。
文件的读取
FileReader类:
File file = new File(fileName);
if (!file.exists()) {
file.createNewFile();
}
FileReader filereader new FileReader(file);
char c = (char)filereader.read(); //读取单个字符,返回值为int类型,代表该字符的ascii码值
filereader.close();
read()方法一个一个读取字符是比较耗费时间的,为了提高效率可以使用BufferedReader对Reader进行包装提高读取速度,使用readLine()方法一行一行的读取文本。
BufferedReader类(对FileReader进行了包装,效率更高):
File file = new File(fileName);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(file)); //接受一个Reader对象
String str = bufread.readLine() //readLine()方法一次性将缓存区内容全部读取到str中,即可以读取文件的一行
bufferedReader.close();
Scanner类:
File myFile = new File("Customers.txt");
Scanner inputFile = new Scanner(myFile);
//使用nextline()方法进行按行读取,nextline方法会一行一行的读取并返回该行的String对象
Scanner keyboard = new Scanner(System.in);
String filename = keyboard.nextLine();
File file = new File(filename);
Scanner inputFile = new Scanner(file);
String line = inputFile.nextLine(); // 读取文件的第一行
System.out.println("The first line in the file is:");
System.out.println(line);
inputFile.close();
Scanner类的hasNext()能够判断当前读取位置之后时候还有数据。为了防止抛出异常,我们可以在执行读取方法之前使用hasNext()方法进行判断。
while (inputFile.hasNext()) {
String friendName = inputFile.nextLine();
System.out.println(friendName);
}
读取文件中的原始数据,如果我们并不想得到一个String对象来表示一个数字或字符,我们可以使用Scanner的其他方法来读取数据。比如nextByte, nextDouble, nextFloat, nextInt, nextLine, nextLong等方法来读取不同类型的数据。
//计算Number.txt文件中数据的总和
while (inputFile.hasNext()) {
double number = inputFile.nextDouble();
sum = sum + number;
}