Java学习之转换流、高效流和序列化流
一.转化流
转换流:可以查指定的编码表进行读写。
OutputStreamWriter(字符流转向字节流的桥梁)
- 1.将程序中的字符按照创建转换流时,给出的编码格式,去查对应的码表(GBK就去查GBK的码表)。
- 2.将查到的两个或三个字节 交给 创建转换流时 传入的字节流
- 3.最终是 使用字节流 将文件写入
InputStreamReader(字节流转向字符流的桥梁)
- 先按字节读 读完了用转换流去查对应的表
- 最终以字符的形式读到程序中
编码格式
mac 默认 UTF-8 一个字3个字节
win 默认 GBK 一个字2个字节
转换流写UTF-8的文件
//转换流写UTF-8的文件
public static void getWriterUTF8() throws IOException{
//创建文件字节流
FileOutputStream fos =new FileOutputStream("/Users/lanou/Desktop/Test/hong.txt");
//创建转换流
//使用操作平台的默认格式写文件
OutputStreamWriter osw = new OutputStreamWriter(fos);
// 写
osw.write("无话可说");
//关闭资源
//1.多个流嵌套 只需关最外边的流
//2.自己创建的流 自己关
//3.从系统中获取的流 不用你来关闭
osw.close();
}
转换流读UTF-8的文件
public static void getReadUTF8() throws IOException{
FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/Test/hong.txt");
InputStreamReader isr = new InputStreamReader(fis);
char[] c = new char[1024];
int len = 0;
while ((len = isr.read(c)) != -1) {
System.out.println(new String(c, 0, len));
}
isr.close();
转化流读写GBK文件与读写UTF-8文件类似,在此不做过多赘述。
二.高效流
高效流又称缓冲流
写入数据到流中,字节缓冲输出流 BufferedOutputStream。
读取流中的数据,字节缓冲输入流 BufferedInputStream。
它们的内部都包含了一个缓冲区,通过缓冲区读写,就可以提高了IO流的读写速度。
默认缓冲区大小:8k 8192字节
缓冲流写入
//创建一个缓冲流
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test/liu.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//写入
bos.write("wanghong".getBytes());
//关闭资源
bos.close();
缓冲流读取
//缓冲流读取
FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/Test/lalal.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] bs = new byte[1024];
int len =0;
while ((len = bis.read(bs)) != -1) {
System.out.println(new String(bs, 0, len));
}
bis.close();
高效字符流
高效字符流写入
FileWriter fw = new FileWriter("/Users/lanou/Desktop/Test/lalala.txt");
BufferedWriter bw = new BufferedWriter(fw);
//写
bw.write("白日依山尽");
//换行
bw.newLine();
bw.write("黄河入海流");
bw.newLine();
bw.write("欲穷千里目");
bw.newLine();
bw.write("更上一层楼");
bw.newLine();
//刷新
bw.flush();
bw.close();
高效字符流读取
//读取文件
FileReader fr = new FileReader("/Users/lanou/Desktop/Test/lalala.txt");
BufferedReader br = new BufferedReader(fr);
String string = "" ;
//读取一行字符串方法 读到文件末尾 返回null
while ((string = br.readLine()) != null) {
// 注意:该方法不能读取到换行符
System.out.print(string);
}
br.close();
三.AutoCloseable接口
JDK1.7版本,所有流都实现了该接口,实现流的自动关闭。
public static void main(String[] args) {
try (
// 流都实现了这个接口
// 当程序结束时 该流对象与会 调用自己本类中 重写close方法
// 注意:不实现AutoCloseable接口
// 不能跟小括号中使用
MyClose myClose = new MyClose();
) {
} catch (Exception e) {
// TODO: handle exception
}
}
class MyClose implements AutoCloseable{
@Override
public void close() throws Exception {
System.out.println("快乐就完事了");
}
}
四.Properties集合
- Properties集合(双列集合 是 Hashtable的子类)
- 该集合 是唯一一个能和 IO流有关的集合
- 注意:一般该集合只存储 字符串类型的键值对
- load:将文件直接读入到集合中
- store:将集合中的键值对直接写入到文件中
- 读取文件的格式
- key=value
- 注意:
- 1.等号前后别加空格
- 2.一般该文件使用.properties(起标识作用)
- 3.#为注释
写
// 将集合写入文件
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test/wh.properties");
Properties properties = new Properties();
// 保存键值对
properties.setProperty("name", "wanghong");
properties.setProperty("age", "24");
properties.setProperty("gender", "man");
// 写入到文件中
// 参数2:传入的注释(推荐英文)
properties.store(fos, "hahaha");
fos.close();
读
// 将文件直接读入集合中
FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/Test/wanghong.properties");
// 创建集合
Properties properties = new Properties();
// 加载文件
properties.load(fis);
// 迭代器遍历
Enumeration<?> enumeration = properties.propertyNames();
while (enumeration.hasMoreElements()) {
//取出每一个元素
String key= (String) enumeration.nextElement();
System.out.println(key + "=" + properties.getProperty(key));
}
fis.close();
}
五.序列化流(反序列化流 对象流)
- 将对象直接写入到文件中
- ObjectOutputStream
- ObjectInputStream
写入
public static void writerObject() throws FileNotFoundException, IOException {
// 将对象写入文件
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test/mj.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 直接写入
// 要保存的对象的类 NotSerializableException 没有实现序列化接口
// Serializable 序列化接口是个标志性接口
// 标识这个对象 可以进行序列化
oos.writeObject(new Person("王宏", 24));
//关闭流
oos.close();
}
读取
public static void readObject() throws FileNotFoundException, IOException, ClassNotFoundException {
// 读取文件
FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/Test/wh.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
// ClassNotFoundException 找不到这个类
// 将文件中的对象进行反序列化 需要依赖
// 存入对象的.class文件
Object readObject = ois.readObject();
System.out.println(readObject);
ois.close();
}
解决序列化ID冲突的方法
将序列化号写死
只要你类中有序列化号
系统将不会为你重新生成
private static final long serialVersionUID = 9077115150567710555L;