0、
由于计算机中的数据基本都保存在硬盘中,因此操作文件中的数据是一种很常见的操作。在操作文件时,最常见的就是从文件中读取数据并将数据写入文件,即文件的读写。针对文件的读写,JDK 专门提供了两个类,分别是 FileInputStream 和 FileOutputStream。
1、
FileInputStream 是 InputStream 的子类,它是操作文件的字节输入流,专门用于读取文件中的数据。由于从文件读取数据是重复的操作,因此需要通过循环语句来实现数据的持续读取。
接下来通过一个案例来实现字节流对文件数据的读取。首先在 Eclipse 项目的根目录下创建一个文本文件 test.txt,在文件中输入内容“itcast”并保存。然后创建一个读取文本的类,具体代码如下所示。
import java.io.FileInputStream;
public class example01 {
public static void main(String[] args) throws Exception{
//创建一个文件字节输入流
FileInputStream in = new FileInputStream("text.txt");
//定义一个 int 类型变量 b,记住每次读取的一个字节
int b = 0;
while (true) {
b = in.read(); //变量 b 记住读取的一个字节
if (b == -1) { //如果读取的字节为 -1,说明读取到了文本末尾,跳出 while 循环
break;
}
System.out.println(b);
}
in.close();
}
}
console:
105
116
99
97
115
116
代码块中创建的字节流 FileInputStream 通过 read()方法将当前项目中的文件“test.txt”中的数据读取并打印。通常情况下读取文件应该输出字符,这里之所以输出数字是因为硬盘上的文件是以字节的形式存在的。在“test.txt”文件中,字符‘i’’、‘t’、‘c’、‘a’、‘s’、‘t’各占一个字节,因此,最终结果现实的就是文件“test.txt”中的六个字节所对应的十进制数。需要注意的是,在读取文件数据时,必须保证文件在相应目录存在并且是可读的,否则会出现文件找不到的异常 FileNotFoundException。
2、
与 FileInputStream 相对应的是 FileOutputStream。FileOutputStream 是 OutputStream 的子类,它是操作文件的字节输入流,专门用于把数据写入文件。接下来通过一个案例演示如何将数据写入文件,如下所示。
import java.io.FileOutputStream;
public class example02 {
public static void main(String[] args) throws Exception{
//创建一个文件输出流
FileOutputStream out = new FileOutputStream("example.txt");
String string = "传智播客";
byte[] b = string.getBytes(); //getBytes()方法可以将字符串转化成字节数组 byte[]
for (int i = 0; i < b.length; i++) {
out.write(b[i]);
}
out.close();
}
}
程序运行后,会在当前根目录下生成一个新的文本文件 example.txt(运行程序后,该文件可能不会立刻显示在项目目录下,强制刷新即可),打开此文件,可以看到如下内容。
2.1、
从运行结果可以看出,通过 FileOutputStream 写数据时,自动创建了文件 example.txt,并将数据写入文件。需要注意的是,如果是通过 FileOutputStream 向一个已经存在的文件中写入数据,那么该文件中的数据首先会被清空,再写入新的数据。若希望在已存在的文件内容之后追加新内容,则可使用 FileOutputStream 的构造函数 FileOutputStream(String fileName, boolean append)来创建文件输出流对象,并把 append 参数的值设置为 true。接下来通过一个案例来如何将数据追加到文件末尾,如下所示。
import java.io.*;
public class example03 {
public static void main(String[] args) throws Exception{
OutputStream out = new FileOutputStream("example.txt",true); //这里使用到了面对对象的多态特性
String string = "欢迎你";
byte[] b = string.getBytes();
for (int i = 0; i < b.length; i++) {
out.write(b[i]);
}
out.close();
}
}
程序运行后,查看项目当前目录下的文件“example.txt”,如下所示。
从上图可以看出,程序同故宫字节输出流对象向文件“example.txt”写入“欢迎你”后,并没有将文件之前的数据清空,而是将新写入的数据追加到了文件的末尾。
3、
由于 IO 流在进行读写操作时会出现异常,在上面的程序中使用了 throws 关键字将异常抛出。然而一旦遇到 IO 异常,IO 流的 close()方法将无法得到执行,通常将关闭流的操作写在 finally 代码块中,接下来演示使用 try catch 方法抛出异常,如下所示。
import java.io.*;
public class example03.1 {
public static void main(String[] args) {
OutputStream out = null;
try {
out = new FileOutputStream("example.txt", true);
String string = "欢迎你";
byte[] b = string.getBytes();
for (int i = 0; i < b.length; i++) {
out.write(b[i]);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally { //将 close()方法写在 finally 中,使用 try catch 抛出异常,执行 close()方法
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}