Java IO专题——字符流和序列化

1.字符流

1)编码问题

2)认识文本和文本文件:Java的文本(char)是16位无符号整数,是字符的Unicode编码(双字节编码);文件是byte byte byte...的数据序列;文本文件是文本(char)序列按照某种编码方案(UTF-8、UTF-16、GBK)序列化为byte的存储结果;

3)字符流(Reader/Writer):字符的处理,一次处理一个字符,字符的底层仍然是基本的字节序列;InputStreamReader→完成byte流解析为char流,按照编码解析,字符流操作的是文本、文本文件;OutputStreamWriter→提供char流到byte流,按照编码处理;

package com.luna.base;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class ReadAndWriteTest {
	public static void main(String[] args) throws IOException{
		FileInputStream in = new FileInputStream("/Users/Gandoph/workspace/BasaInfo/src/file/log.dat");
		InputStreamReader isr = new InputStreamReader(in,"gbk"); //默认项目编码		
		FileOutputStream out = new FileOutputStream("/Users/Gandoph/workspace/BasaInfo/src/file/log.dat");
		OutputStreamWriter osw = new OutputStreamWriter(out, "gbk");
		
//		int c;
//		while((c=isr.read())!=-1){
//			System.out.print((char)c);
//		}
		
		/*
		 * 批量读取放入buffer这个字符数组,从第0个位置开始放置,最多放buffer.length个
		 * 返回的是读到的字符的个数
		 */
		char[] buffer = new char[8*1024];
		int c;
		while((c=isr.read(buffer,0,buffer.length))!=-1){
			String s = new String(buffer,0,c);
			System.out.print(s);
			osw.write(buffer,0,c);
			osw.flush();
		}
		isr.close();
		osw.close();
	}
}

     4)FileReader/FileWriter

package com.luna.base;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FrAndFwTest {
	public static void main(String[] args) throws IOException{
		FileReader fr = new FileReader("/Users/Gandoph/workspace/BasaInfo/src/file/log.dat");
		//参数true表示在源文件后面追加
		FileWriter fw = new FileWriter("/Users/Gandoph/workspace/BasaInfo/src/file/log1.dat", true);
		char[] buffer = new char[2056];
		int c;
		while((c = fr.read(buffer, 0, buffer.length))!=-1){
			fw.write(buffer,0,c);
			fw.flush();
		}
		fr.close();
		fw.close();
	}
}

    5)BufferedReader→readLine()一次读一行,BufferedWriter/PrintWriter→写一行,代码如下:

package com.luna.base;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class BrAndBwAndPw {
	public static void main(String[] args) throws IOException{
		//对文件进行读写操作
		BufferedReader br = new BufferedReader(new InputStreamReader(
				new FileInputStream("/Users/Gandoph/workspace/BasaInfo/src/file/log.dat")));
//		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
//				new FileOutputStream("/Users/Gandoph/workspace/BasaInfo/src/file/log3.dat")));
		PrintWriter pw = new PrintWriter("/Users/Gandoph/workspace/BasaInfo/src/file/log3.dat"); //bw替换方案
		String line;
//		while((line=br.readLine())!=null){
//			System.out.println(line); //一次读一行,并不能识别换行
//			bw.write(line);
//			bw.newLine();//单独写出换行操作
//			bw.flush();
//		}
//		br.close();
//		bw.close();
		
		while((line=br.readLine())!=null){
			System.out.println(line); //一次读一行,并不能识别换行
			pw.println(line);
			pw.flush();
		}
		br.close();
		pw.close();
	}
}

2.对象的序列化、反序列化

1)对象的序列化就是将Object转化成byte序列,反之叫对象的反序列化;

2)序列化流(ObjectOutputStream)是过滤流——writeObject;反序列化流(ObjectInputStream)——readObject;

3)序列化接口(Serializable):对象必须实现序列化接口才能进行序列化,否则将出现异常;这个接口没有任何方法,只是一个标准;Student实例类如下:

package com.luna.base;
import java.io.Serializable;
public class Student implements Serializable{
	private static final long serialVersionUID = 7446182117116524275L;
	private String name;
	private int age;
	private transient String no; //该元素不会进行JVM默认的序列化,可以自己完成这个元素的序列化
	public Student() {
	        super();
	}
	public Student(String name, Integer age, String no) {
		super();
		this.name = name;
		this.age = age;
		this.no = no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getNo() {
		return no;
	}
	public void setNo(String no) {
		this.no = no;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", no=" + no + "]";
	}
}

Student序列化反序列化类,如下所示:

package com.luna.base;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ObjectSerialDemo {
	public static void main(String[] args) throws Exception{
		String file = "/Users/Gandoph/workspace/BasaInfo/src/file/log.dat";
//		ObjSerial(file); //注意先执行序列化方法,后执行反序列化方法
		ObjUnSerial(file);
	}
	
	public static void ObjSerial(String file) throws IOException{
		//对象序列化
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
		Student stu = new Student("zhansan",20,"1001");
		oos.writeObject(stu);
		oos.flush();
		oos.close();
		System.out.println(stu);
	}
	
	public static void ObjUnSerial(String file) throws Exception{
		//对象反序列化
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
		Student student = (Student)ois.readObject();
		System.out.println(student);
		ois.close();
	}
}

4)transient关键字,注意自行序列化的方法签名:

private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException

private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException

自行实现transient序列化的Student实例类,此时transient元素也可以进行序列化,如下所示:

package com.luna.base;
import java.io.Serializable;
public class Student implements Serializable{
	private static final long serialVersionUID = 7446182117116524275L;
	private String name;
	private int age;
	private transient String no; //该元素不会进行JVM默认的序列化,可以自己完成这个元素的序列化
	public Student() {
		super();
	}
	public Student(String name, Integer age, String no) {
		super();
		this.name = name;
		this.age = age;
		this.no = no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getNo() {
		return no;
	}
	public void setNo(String no) {
		this.no = no;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", no=" + no + "]";
	}
	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{
		s.defaultWriteObject(); //把JVM能默认序列化的元素进行序列化操作
		s.writeUTF(no); //自己完成no的序列化
	}
	private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
		s.defaultReadObject(); //把JVM能默认反序列化的元素进行反序列化操作
		this.no = s.readUTF(); //自己完成no的反序列化操作
		
	}
}

    分析ArrayList源码中序列化和反序列化的问题:ArrayList不一定放满,故只序列化有效元素。

5)序列化中子类和父类构造函数的调用问题:对子类对象进行反序列化操作时,如果其父类没有实现序列化接口,那么其父类的构造函数会被调用,代码如下:

package com.luna.base;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectSerialTest {
	public static void main(String[] args) throws Exception{
//		serialObject();
//		serialUnObject();
//		serialObjectBar();
		serialUnObjectBar();
	}
	
	//序列化方法Foo
	public static void serialObject() throws IOException{
		ObjectOutputStream oos = new ObjectOutputStream(
				new FileOutputStream("/Users/Gandoph/workspace/BasaInfo/src/file/log.dat"));
		Foo2 foo2 = new Foo2();
		oos.writeObject(foo2);
		oos.flush();
		oos.close();
	}
	
	//序列化方法Bar
	public static void serialObjectBar() throws IOException{
		ObjectOutputStream oos = new ObjectOutputStream(
				new FileOutputStream("/Users/Gandoph/workspace/BasaInfo/src/file/log.dat"));
		Bar2 bar2 = new Bar2();
		oos.writeObject(bar2);
		oos.flush();
		oos.close();
	}
	
	//反序列化方法:反序列化是否递归调用父类的构造方法Foo
	public static void serialUnObject() throws Exception{
		ObjectInputStream ois = new ObjectInputStream(
				new FileInputStream("/Users/Gandoph/workspace/BasaInfo/src/file/log.dat"));
		Foo2 foo2 = (Foo2)ois.readObject();
		System.out.println(foo2);
		ois.close();
	}
	
	//反序列化方法:反序列化是否递归调用父类的构造方法Bar
	public static void serialUnObjectBar() throws Exception{
		ObjectInputStream ois = new ObjectInputStream(
				new FileInputStream("/Users/Gandoph/workspace/BasaInfo/src/file/log.dat"));
		Bar2 bar2 = (Bar2)ois.readObject();
		System.out.println(bar2);
		ois.close();
	}
}
/*
 * 一个类实现了序列化接口,那么其子类都可以进行序列化
 */
class Foo implements Serializable{
	public Foo(){
		System.out.println("foo...");
	}
}
class Foo1 extends Foo{
	public Foo1(){
		System.out.println("foo1...");
	}
}
class Foo2 extends Foo1{
	public Foo2(){
		System.out.println("foo2...");
	}
}
class Bar{
	public Bar(){
		System.out.println("bar...");
	}
}
class Bar1 extends Bar implements Serializable{
	public Bar1(){
		System.out.println("bar...");
	}
}
class Bar2 extends Bar1{
	public Bar2(){
		System.out.println("bar2...");
	}
}

原文链接:https://mp.csdn.net/postedit/80384321

猜你喜欢

转载自blog.csdn.net/u011635492/article/details/80384321
今日推荐