字节流
文件输入输出流
==FileInputStream和FileOutputStream==
Java提供了一系列的读写文件的类和方法。在Java 中,所有的文件都是字节形式的。Java提供从文 件读写字节的方法。而且,Java允许在字符形式 的对象中使用字节文件流。
两个最常用的流类是FileInputStream和 FileOutputStream,它们生成与文件链接的字节流。 为打开文件,你只需创建这些类中某一个类的一 个对象,在构造方法中以参数形式指定文件的名称
当你对文件的操作结束后,需要调用close( )来关闭文件。
读取音频,图片等数据的时候只能使用字节流,下面来看一下使用文件流实现复制的功能。(这里主要说IO流,对于异常我直接抛出,后面不在提及)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package com.qf.byteio.test;
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;
/** * 功能:通过字节输入输出流,完成文件copy InputStream OutputStream * 分析: * 源文件 程序 目标文件 * 1.找到源文件 * 2.读取源文件里的信息 输入 程序 * 3.将程序读到的数据 写入 源文件 * * */ public class TestCopy3 { public static void main(String[] args) throws IOException { //1.选择合适流 InputStream OutputStream FileInputStream fis=new FileInputStream(new File("D:\\qf1717\\Wildlife.wmv")); FileOutputStream fos=new FileOutputStream(new File("D:\\qf1717\\Wildlife(复制).wmv")); //2.处理数据 //2.1 创建缓存区 byte [] buf=new byte[1024]; //2.2从缓存区读数据 int len = fis.read(buf); while(len!=-1){ //将读的数据写入 新文件中 fos.write(buf); len=fis.read(buf);//注意点 len再次赋值 读 缓存区的数据 } //3.关流 fos.close(); fis.close(); System.out.println("复制完成"); } }
|
文件的复制例子1:(一个字符一个字符的读)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream;
/** * 功能:通过字节输入输出流,完成文件copy InputStream OutputStream * 分析: * 源文件 程序 目标文件 * 1.找到源文件 * 2.读取源文件里的信息 输入 程序 * 3.将程序读到的数据 写入 源文件 * * 第一步:找到源文件 读取源文件里的信息 输入 程序 * 将程序读到内容打印到控制台 * 流的操作 * 1选择合适的流(流的分类) * 2处理数据 * 3.关流 * * */ public class TestInputStream2 { public static void main(String[] args) throws IOException { //找到源文件 读取源文件里的信息 输入 程序 将程序读到内容打印到控制台 //1选择合适的流(流的分类) File f=new File("D:\\qf1717\\abc.txt"); //File f=new File("D:/qf1717/abc.txt"); InputStream fis=new FileInputStream(f); //2处理数据 /*int n=fis.read();//97 while(n!=-1){ System.out.print((char)n); n=fis.read();//迭代式 -1 }*/ int n=0; while((n=fis.read())!=-1){//97 System.out.print((char)n); } //3关流 fis.close(); } }
|
文件的复制例子2:(使用临时处理区,多个字符的读)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package com.qf.byteio.test;
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Arrays;
/** * 功能:通过字节输入输出流,完成文件copy InputStream OutputStream * 分析: * 源文件 程序 目标文件 * 1.找到源文件 * 2.读取源文件里的信息 输入 程序 * 3.将程序读到的数据 写入 源文件 * * 第一步:找到源文件 读取源文件里的信息 输入 程序 * 将程序读到内容打印到控制台 * 流的操作 * 1选择合适的流(流的分类) * 2处理数据 * 3.关流 * * */ public class TestInputStream4 { public static void main(String[] args) throws IOException { //找到源文件 读取源文件里的信息 输入 程序 将程序读到内容打印到控制台 //1选择合适的流(流的分类) File f=new File("D:\\qf1717\\abc.txt"); //File f=new File("D:/qf1717/abc.txt"); InputStream fis=new FileInputStream(f); //2处理数据 //2.1 创建一个临时区域 一次性存多个值 byte [] buf=new byte[1024];//abcdef //2.2从临时区域读数据 /*int len=fis.read(buf); //System.out.println(len);//字节数 //System.out.println(Arrays.toString(buf)); System.out.println(new String(buf)); System.out.println(new String(buf,0,len));//0 5 */ int len=fis.read(buf); while(len!=-1){ System.out.println(new String(buf,0,len)); len=fis.read(buf); } //3关流 fis.close(); } }
|
available( )判定剩余的字节个数及怎样用,skip( )方法跳过不必要的字节
文件的复制例子2:(使用临时处理区,多个字符的读)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;
/** * 功能:通过字节输入输出流,完成文件copy InputStream OutputStream * 分析: * 源文件 程序 目标文件 * 1.找到源文件 * 2.读取源文件里的信息 输入 程序 * 3.将程序读到的数据 写入 源文件 * * 将程序读到的数据写入目标文件 */ public class TestOutputStream2 { public static void main(String[] args) throws IOException { //1.选择合适的流 FileOutputStream fos=new FileOutputStream(new File("D:\\qf1717\\byte写1.txt")); //2.处理数据 String s="abcdefghijklmn"; byte[] buf = s.getBytes(); fos.write(buf); //3.关闭流 fos.close(); System.out.println("程序结束"); } }
|
注意:
文件输出流有个构造方法两个参数,
public FileOutputStream(File file, boolean append)
file - 为了进行写入而打开的文件。
append - 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处 ,默认是false
字节数组输入输出流
==ByteArrayInputStream和ByteArrayOutputStream==
字节数组输入输出流又称为内存流,下面通过内存流实现图片的复制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| package com.qf.bytearrayio.test;
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;
/** * 文件字节输入流 文件字节输出流 字节数组输入流 字节数组输出流 * 功能:借助 内存流完成图片copy * 分析: * 文件字节输入流 找到资源文件 read * 字节数组输出流 写 * 程序 * 字节数组输入流 读 * 文件字节输出流 写 */ public class TestCopy { public static void main(String[] args) throws IOException { //创建流的对象 FileInputStream fis=new FileInputStream(new File("Koala.jpg")); ByteArrayOutputStream bos=new ByteArrayOutputStream(); //处理数据 byte [] buf=new byte[1024]; int len=fis.read(buf); while(len!=-1){ //写 bos.write(buf, 0, len); //再读 len=fis.read(buf); } System.out.println("写入内存流中成功"); byte[] buf1 = bos.toByteArray();//将内存流中的数据取出形参字节数组 //读的流的对象 ByteArrayInputStream bis=new ByteArrayInputStream(buf1); FileOutputStream fos=new FileOutputStream(new File("Koala(复制).jpg")); //处理数据 /*int n = bis.read(); while(n!=-1){ fos.write(n); n=bis.read(); }*/ int n=0; while((n=bis.read())!=-1){ fos.write(n); } //关闭流 fos.close(); bis.close(); bos.close(); fis.close(); System.out.println("复制完成"); } }
|
注意:
- writeTo方法:将此字节数组输出流的全部内容写 入到指定的输出流参数中
- reset:将此字节数组输出流的 count 字段重置 为零,从而丢弃输出流中目前已累积的所有输 出。通过重新使用已分配的缓冲区空间,可以再次使用该输出流
使用内存流实现数据的读写操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException;
/** * 字节数组输入流 : * ByteArrayInputStream:内存流 * 读 * String.getBytes(): String ------>byte[] * 字节数组输出流: * ByteArrayOutputStream:内存流 * 写 * bos.toByteArray();将内存中数据取出来 转换为字节数组 */ public class Test2 { public static void main(String[] args) throws IOException { //1.选择合适的流 ByteArrayOutputStream bos=new ByteArrayOutputStream(); //向字节数组输出流写入数据 bos.write("nihao123".getBytes()); System.out.println("写入成功"); //2.处理数据 //将内存流的数据转换为字节数组 byte[]** byte[] buf = bos.toByteArray(); System.out.println(buf.length);//nihao123 ByteArrayInputStream bis=new ByteArrayInputStream(buf);//byte[] //从内存数组输入流读到数据 打印到控制台 byte [] buf1=new byte[1024]; int len = bis.read(buf1); while(len!=-1){ System.out.println(new String(buf1,0,len)); len=bis.read(buf1); } //3关闭流 bos.close(); bis.close(); System.out.println("程序结束"); } }
|
缓冲流
==BufferedInputStream和BufferedOutputStream==
实现图片的复制:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;
public class TestCopy { public static void main(String[] args) { //1.选择合适的流 BufferedInputStream bis=null; BufferedOutputStream bos=null; try { bis = new BufferedInputStream(new FileInputStream("D:\\qf1717\\Koala.jpg")); bos = new BufferedOutputStream(new FileOutputStream("D:\\qf1717\\Koala复制(BUF).jpg")); //2.处理数据 byte [] buf=new byte[1024]; int len=bis.read(buf); while(len!=-1){ bos.write(buf, 0, len);//保证最后一次读取数据有效 len=bis.read(buf); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(bos!=null){ //3.关闭流 try { bos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(bis!=null){ try { bis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } System.out.println("复制完成"); } }
|
注意:
- public BufferedInputStream(InputStream in,int size)这个构造方法中size默认的大小是8192
- 用flush()方法更新流,要想在程序结束之前将缓冲区里的数据写 入磁盘,除了填满缓冲区或关闭输出流外, 还可以显式调用flush()方法
处理流
==DataInputStream和DataOutputStream==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| package com.qf.dataio.test;
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;
/** * DataInputStream DataOutputStream * 里面提供存储java基本数据类型: 四类八种 String * 处理流 只针对字节流 (二进制文件) * IOException 的子类 java.io.EOFException * EOF:End of File */ public class Test1 { public static void main(String[] args) throws IOException { //write(); //read(); System.out.println(System.getProperties()); } public static void write() throws IOException{ //1.选择合适的流 FileOutputStream fos=new FileOutputStream(new File("D:\\qf1717\\DataIO.txt")); BufferedOutputStream bos=new BufferedOutputStream(fos); DataOutputStream dos=new DataOutputStream(bos); //2.处理数据 //基本数据类型 dos.writeInt(12); dos.writeDouble(34.5); dos.writeChar('A'); dos.writeBoolean(true); //处理字符串 dos.writeUTF("我爱你中国"); //3.关闭流 dos.close(); } public static void read() throws IOException{ //1.选择合适的流 FileInputStream fis=new FileInputStream(new File("D:\\qf1717\\DataIO.txt")); BufferedInputStream bis=new BufferedInputStream(fis); DataInputStream dis=new DataInputStream(bis); //2.处理数据 //基本数据类型 System.out.println(dis.readInt()); System.out.println(dis.readDouble()); System.out.println(dis.readChar()); System.out.println(dis.readBoolean()); //String System.out.println(dis.readUTF()); //3.关闭流 dis.close(); } }
|
打印流
==PrintStream==
功能:键盘录入信息 通过打印流 将数据保存到文件中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter;
public class Test2 { public static void main(String[] args) throws IOException { //1.选择合适的流 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); PrintWriter pw=new PrintWriter(new FileWriter(new File("D:\\qf1717\\123(打印流).txt"))); //2.处理数据 String data = br.readLine(); while(data!=null){ pw.write(data); pw.flush(); data=br.readLine(); } //3关闭流 pw.close(); br.close(); } }
|
对象流
==ObjectInputStream和ObjectOutputStream==
这里涉及到对象的序列化和反序列化,这里我来简单的介绍一下。
序列化
将对象转换为字节流保存起来,并在以后 还原这个对象,这种机制叫做对象序列化,将一个对象保存到永久存储设备上称为持久化, 一个对象要想能够实现序列化,必须实现 Serializable接口或Externalizable接口。
序列化(serialization)是把一个对象的状态写入 一个字节流的过程。当你想要把你的程序状态存 到一个固定的存储区域例如文件时,它是很管用 的。稍后一点时间,你就可以运用序列化过程存储这些对象
假设一个被序列化的对象引用了其他对象,同样,其他对象又引用了更多的对象对象 和它们的关系形成了一个顺序图表。图表中也有循环引用。也就是说,对象X可以含有一个对象Y的引用,对象Y同样可以包含一个对象X的引用。对象同样可以包含它们自己的引用。对象序列化和反序列化的工具被设计出来并在这 一假定条件下运行良好。如果你试图序列化一个 对象图表中顶层的对象,所有的其他的引用对象 都被循环的定位和序列化。同样,在反序列化过 程中,所有的这些对象以及它们的引用都被正确 的恢复
• 当一个对象被序列化时,只保存对象的非静态成 员变量,不能保存任何的成员方法和静态的成员 变量。
• 如果一个对象的成员变量是一个对象,那么这个 对象的数据成员也会被保存。
• 如果一个可序列化的对象包含对某个不可序列化 的对象的引用,那么整个序列化操作将会失败, 并且会抛出一个NotSerializableException。我 们可以将这个引用标记为transient,那么对象仍 然可以序列化
Serializable接口
- 只有一个实现Serializable接口的对象可以被 序列化工具存储和恢复。Serializable接口没 有定义任何成员。它只用来表示一个类可以被 序列化。如果一个类可以序列化,它的所有子 类都可以序列化。
- 声明成transient的变量不被序列化工具存储。 同样,static变量也不被存储
Externalizable接口
- Java的序列化和反序列化的工具被设计出来,所以很多存 储和恢复对象状态的工作自动进行。然而,在某些情况下, 程序员必须控制这些过程。例如,在需要使用压缩或加密 技术时,Externalizable接口为这些情况而设计。
Externalizable 接口定义了两个方法:
- – void readExternal(ObjectInput inStream) throws IOException, ClassNotFoundException
- – void writeExternal(ObjectOutput outStream) throws IOException
这些方法中,inStream是对象被读取的字节流,outStream是 对象被写入的字节流。
• Externalizable 实例类的惟一特性是可以 被写入序列化流中,该类负责保存和恢复 实例内容。 若某类要完全控制某一对象及 其超类型的流格式和内容,则它要实现 Externalizable 接口的 writeExternal 和 readExternal 方法。这些方法必须显式与 超类型进行协调以保存其状态。这些方法 将代替自定义的 writeObject 和 readObject 方法实现
接下来我们来看个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package com.qf.objectio.test;
import java.io.Serializable;
public class Student implements Serializable{ private int sid; private String name; private int age; public Student() { super(); } public Student(int sid, String name, int age) { super(); this.sid = sid; this.name = name; this.age = age; } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } 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; } @Override public String toString() { return "Student [sid=" + sid + ", name=" + name + ", age=" + age + "]"; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package com.qf.objectio.test;
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream;
/** * 对象流 * 对象序列化: 对象数据 -------》 文件 (二进制文件) * 对象反序列化:文件中的数据----->对象 * java.io.NotSerializableException: com.qf.objectio.test.Student * * 联通 UTF-8** */ public class TestStudent { public static void main(String[] args) throws IOException, ClassNotFoundException { //writeObject(); readObject(); } public static void writeObject() throws IOException{ //1.选择合适的流 FileOutputStream fos=new FileOutputStream(new File("D:\\qf1717\\对象流.txt")); ObjectOutputStream oos=new ObjectOutputStream(fos); //2.处理数据 Student stu1=new Student(1001,"aa",17); oos.writeObject(stu1);//Object //3.关闭流 oos.close(); System.out.println("完成"); } public static void readObject() throws IOException, ClassNotFoundException{ //1.选择合适的流 FileInputStream fis=new FileInputStream(new File("D:\\qf1717\\对象流.txt")); ObjectInputStream ois=new ObjectInputStream(fis); //2.处理数据 Student stu=(Student)ois.readObject(); System.out.println(stu); System.out.println(stu.getSid()+"\t"+stu.getName()+"\t"+stu.getAge()); //3.关闭流 ois.close(); } }
|
那么当我们可序列化的对象引用了其他的对象的时候结果怎样呢,我们继续来看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import java.io.Serializable;
public class Grade implements Serializable { /** * */ private static final long serialVersionUID = 7208450044584117263L; private int gid; private String gname; public Grade(int gid, String gname) { super(); this.gid = gid; this.gname = gname; } public Grade() { super(); } public int getGid() { return gid; } public void setGid(int gid) { this.gid = gid; } public String getGname() { return gname; } public void setGname(String gname) { this.gname = gname; } @Override public String toString() { return "Grade [gid=" + gid + ", gname=" + gname + "]"; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| package com.qf.objectio.test;
import java.io.Serializable;
public class Student2 implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private int sid; private static String name="张三"; private transient int age=18;//瞬时属性 private Grade grade; public Student2() { super(); } public Student2(int sid, String name, int age) { super(); this.sid = sid; this.name = name; this.age = age; } public Student2(int sid, String name, int age, Grade grade) { super(); this.sid = sid; this.name = name; this.age = age; this.grade = grade; } public Grade getGrade() { return grade; } public void setGrade(Grade grade) { this.grade = grade; } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } 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; } @Override public String toString() { return "Student [sid=" + sid + ", name=" + name + ", age=" + age + "]"; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| package com.qf.objectio.test;
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * * java.io.NotSerializableException: com.qf.objectio.test.Grade * */ public class TestStudent2 { public static void main(String[] args) throws IOException, ClassNotFoundException { writeObject(); readObject(); } /** * 序列化 * @throws IOException */ public static void writeObject() throws IOException{ //1.选择合适流 FileOutputStream fos=new FileOutputStream(new File("D:\\qf1717\\对象流2.txt")); ObjectOutputStream oos=new ObjectOutputStream(fos); //2处理数据 Grade g=new Grade(1,"1717"); Student2 stu1=new Student2(1001,"aa",17,g); oos.writeObject(stu1); //3.关闭流 oos.close(); System.out.println("完成"); } /** * 反序列化 * @throws IOException * @throws ClassNotFoundException */ public static void readObject() throws IOException, ClassNotFoundException{ //1.选择合适的流 FileInputStream fis=new FileInputStream(new File("D:\\qf1717\\对象流2.txt")); ObjectInputStream ois=new ObjectInputStream(fis); //2.处理数据 Student2 stu1=(Student2)ois.readObject(); System.out.println(stu1); System.out.println(stu1.getGrade().getGid()); System.out.println(stu1.getGrade().getGname()); //3.关闭流 ois.close(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| package com.qf.objectio.test;
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream;
/** * 对象流 * 对象序列化: 对象数据 -------》 文件 (二进制文件) * 对象反序列化:文件中的数据----->对象 * java.io.NotSerializableException: com.qf.objectio.test.Student * * 联通 UTF-8** */ public class TestStudent3 { public static void main(String[] args) throws IOException, ClassNotFoundException { //writeObject(); readObject(); } public static void writeObject() throws IOException{ //1.选择合适的流 FileOutputStream fos=new FileOutputStream(new File("D:\\qf1717\\对象流.txt")); ObjectOutputStream oos=new ObjectOutputStream(fos); //2.处理数据 Student stu1=new Student(1001,"aa",17); Student stu2=new Student(1002,"aa",18); Student stu3=new Student(1003,"aa",19); Student stu4=new Student(1004,"aa",17); Student stu5=new Student(1005,"aa",16); oos.writeInt(5); oos.writeObject(stu1);//Object oos.writeObject(stu2);//Object oos.writeObject(stu3);//Object oos.writeObject(stu4);//Object oos.writeObject(stu5);//Object //3.关闭流 oos.close(); System.out.println("完成"); } public static void readObject() throws IOException, ClassNotFoundException{ //1.选择合适的流 FileInputStream fis=new FileInputStream(new File("D:\\qf1717\\对象流.txt")); ObjectInputStream ois=new ObjectInputStream(fis); //2.处理数据 /*Student stu1=(Student)ois.readObject(); System.out.println(stu1); Student stu2=(Student)ois.readObject(); System.out.println(stu2); Student stu3=(Student)ois.readObject(); System.out.println(stu3); Student stu4=(Student)ois.readObject(); System.out.println(stu4); Student stu5=(Student)ois.readObject(); System.out.println(stu5);*/ int count = ois.readInt(); for(int i=0;i<count;i++){ Student stu=(Student)ois.readObject(); System.out.println(stu); } //3.关闭流 ois.close(); } }
|
如果边读边写,那么静态变量为输入的数据,瞬时变量为默认值,如果写完之后再读,那么静态变量是初始值,瞬时变量为默认值。
反序列化时不会调用对象的任何构造方法,仅 仅根据所保存的对象状态信息,在内存中重新 构建对象
小结:
一个类若想被序列化,则需要实现java.io.Serializable接口,该接口中没有定义任何方法,是一个标识性接口(Marker Interface),当一个类实现了该接口,就表示这个类的对象是可以序列化的。
2.在序列化时,static变量是无法序列化的;如果A包含了对B的引用,那么在序列化A的时候也会将B一并地序列化;如果此时A可以序列化,B无法序列化,那么当序列化A的时候就会发生异常,这时就需要将对B的引用设为transient,该关键字表示变量不会被序列化。
3.当我们在一个待序列化/反序列化的类中实现了以上两个private方法(方法声明要与上面的保持完全的一致),那么就允许我们以更加底层、更加细粒度的方式控制序列化/反序列化的过程。
csdn博客相关内容