IO流
FileInputStream文件输入流
示例代码
//获取文件输入流filePath为文件路径
FileInputStream fis = new FileInputStream(filePath);
//获取文件中的数据
byte[] bytes = fis.readAllBytes();
//将数据转换为string并打印
System.out.println(new String(bytes));
//关闭输入流
fis.close();
运行结果
FileOutputStream文件输出流
示例代码
//获取文件输出流
FileOutputStream fos = new FileOutputStream(filePath);
//新建字符串
String str = "Hello World";
//将字符串转换为byte数组后写入输出流
fos.write(str.getBytes());
//将输出流写入磁盘
fos.flush();
//关闭输出流
fos.close();
运行结果
FileReader文件字符读取流
读取文件内容
//获取字符流
FileReader fr = new FileReader(filePath);
//新建char数组,用来接收字符流内容
char[] chars = new char[1024];
//读取字符流
fr.read(chars);
//转换为string并打印到控制台
System.out.println(new String(chars));
fr.close();
运行结果
在new char时设置的大小超过了文件内容的字符大小时,显示时会出现乱码。
优化代码
//获取字符流
FileReader fr = new FileReader(filePath);
//新建char数组,用来接收字符流内容
char[] chars = new char[1024];
//len用来获取读取的字符数
int len = 0;
/**
* 当read方法读取到字符时会返回读取到的字符数,此数小于等于new char的大小
* 当read方法多次执行时后一次方法读取的字符会紧接着前一次获取字符后读取
* 例如:new char大小为5,文件的内容为1234567890,第一次read获取到的是12345,第二次read获取到的是67890。
* 当文件中的内容读取完成后,再次执行read方法会返回-1
*/
while ((len = fr.read(chars)) != -1){
/**
* String(char[], int, int)
* char[]:需要转换为string的char数组
* int:开始的位置
* int:结束的位置
*/
System.out.println(new String(chars, 0, len));
}
fr.close();
运行结果
FileWriter文件字符写入流
示例代码
FileWriter fw = new FileWriter(filePath);
fw.write("你好啊!");
fw.flush();
fw.close();
运行结果
缓冲流
缓冲流一共有四种
- BufferedInputStream
- BufferedOutputStream
- BufferedReader
- BufferedWriter
这四种缓冲流需要套接在相应的节点流上使用,缓冲流可以大幅提升节点流的性能。
缓冲流就是将数据缓冲进内存中,在内存中进行IO操作,以此大幅提升IO操作的性能,速度比基于硬盘的IO操作块75000多倍
使用示例
FileInputStream fis = new FileInputStream(filePath);
BufferedInputStream bis = new BufferedInputStream(fis);
//do something
bis.close();
fis.close();
转换流
转换流提供了在字节流和字符流之间的转换
当文件中的内容都是字符时,转换为字符流操作更加高效
OutputStreamWriter输出转换流
示例代码
FileOutputStream fos = new FileOutputStream(filePath);
/**
* 将字节流转换为字符流
* fos:字节流实例
* string:字符编码
*/
OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
osw.write("Hello Hello");
osw.flush();
osw.close();
fos.close();
运行结果
InputStreamReader输入转换流
示例代码
FileInputStream fis = new FileInputStream(filePath);
InputStreamReader isr = new InputStreamReader(fis, "utf-8");
char[] chars = new char[1024];
int len = 0;
while ((len = isr.read(chars)) != -1){
System.out.println(new String(chars, 0, len));
}
isr.close();
fis.close();
输出结果
标准输入输出流
示例代码
//使用字符输入流获取控制台输入数据
InputStreamReader ir = new InputStreamReader(System.in);
//将字符流转换为缓存流
BufferedReader br = new BufferedReader(ir);
System.out.println(br.readLine());
br.close
ir.close
对象流
- 将对象储存在硬盘上时,硬盘储存的基础是二进制,需要减对象转换为一个二进制的字节流,把流保存在硬盘上。
- 对象通过网络传送到另一台机器上,需要将对象转化为二进制的数据流,然后通过网络传输,接收者需要将数据流转化为对象。
- 正是因为保存对象到硬盘(对象的持久化)和对象的网络传输,产生了对象的输入和输出流。
序列化:将对象写入IO流中(ObjectOutputStream)
反序列化:将IO流中恢复对象(ObjectInputStream)
- 注:使用static和transient修饰的成员变量是不可以被序列化的。
- 序列化和反序列化是针对对象的各种属性,不包括类的属性
- 对象序列化与反序列化时使用的类需要严格一致,包名、类名、类机构等等都需要完全一致。
ObjectOutputStream序列化输出流
示例代码
创建Person类用来序列化操作
/**
* 需要序列化操作的类需要继承Serializable
*
*/
public class Person implements Serializable {
/**
* 序列化版本标识符的静态变量
* 表明类的不同版本的兼容性
*/
private static final long serialVersionUID = 1L;
String name;
int age;
}
使用ObjectOutputStream
/**
* 使用FileOutputStream输出序列化后的object
*
*/
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
Person p = new Person();
p.name = "张三";
p.age = 20;
oos.writeObject(p);
oos.flush();
oos.close();
运行结果
ObjectInputStream反序列化输入流
示例代码
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
Object obj = ois.readObject();
Person p = (Person)obj;
System.out.println(p.name);
System.out.println(p.age);
ois.close();
运行结果
RandomAccessFile(随机访问)
- 程序可以直接跳转到文件的任意位置来读写文件
- 支持只访问文件的部分内容
- 可以向已存在的文件后追加内容
RandomAccessFile构造方法
- 参数1:文件路径
- 参数2:读写操作string
- r:只读打开文件
- rw:读写打开
- rwd:读写打开,同步文件内容更新
- rws:读写打开,同步文件内容和数据的更新
读取文件内容
RandomAccessFile raf = new RandomAccessFile(filepath, "r");
//开始读取的字节位置
raf.seek(0);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = raf.read(bytes)) != -1){
System.out.println(new String(bytes, 0, len));
}
raf.close();
运行结果
写入内容
RandomAccessFile raf = new RandomAccessFile(filePath, "rw");
//从头写入内容时会覆盖原文件内容等长的字符
//raf.seek(0);
//从尾部追加内容
raf.seek(raf.length());
raf.write("你好啊".getBytes());
raf.close();
头部写入内容运行结果
尾部追加内容运行结果