ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。
ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。ObjectInputStream 用于恢复那些以前序列化的对象。其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参。
ObjectInputStream 确保从流创建的图形中所有对象的类型与 Java 虚拟机中显示的类相匹配。使用标准机制按需加载类。
ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。
只能将支持 java.io.Serializable 接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。
writeObject 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象。
还可以使用 DataOutput 中的适当方法将基本数据类型写入流中。还可以使用 writeUTF 方法写入字符串。
对象的默认序列化机制写入的内容是:对象的类,类签名,以及非瞬态和非静态字段的值。其他对象的引用(瞬态和静态字段除外)也会导致写入那些对象。可使用引用共享机制对单个对象的多个引用进行编码,这样即可将对象的图形恢复为最初写入它们时的形状。
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class ObjectStreamDemo { public static void main(String [] args)throws Exception{ writeObj(); readObj(); } public static void readObj()throws Exception{//这里抛的是Exception,而不是IOException,因为readObject() ObjectInputStream ois=new ObjectInputStream(new FileInputStream("c:\\obj.txt")); Person p=(Person) ois.readObject(); System.out.println(p); ois.close(); } public static void writeObj()throws IOException{ ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("c:\\obj.txt"));//一般在实际应用当中,后缀名存的都是.object oos.writeObject(new Person("wangda",39,"USA"));//写完后就存在硬盘上,打印的结果还是cn,原因见person表 oos.close(); } }
import java.io.Serializable; public class Person implements Serializable {//实现Serializable public static final long serialVersionUID =421;//这个uid就是指定了该类的序列号,下面改动类的方法属性都能使以后可以读写 String name; transient int age;//对于非静态的成员,也不想将其序列化的话,可以加上关键字修饰。虽然还在堆内存当中,但是还是不能被序列化 static String country="cn";//静态是不能被序列化的,它在方法学里面。而对象是在堆里面。能把堆里面的数据序列化,而不能把其他里面的东西序列化 Person(String name,int age,String country){ this.name=name; this.age=age; this.country=country; } public String toString(){ return name+":"+age+":"+country; } }
import java.io.PipedInputStream; import java.io.PipedOutputStream; //使用多线程,一个是读,一个是写 class Read implements Runnable{ private PipedInputStream in; Read(PipedInputStream in) { this.in=in; } public void run(){ try { System.out.println("读取前..没有数据阻塞"); byte[] buf=new byte[1024]; int len=in.read(); System.out.println("读取后..阻塞结束"); String s=new String(buf,0,len);//把int转化成字符串 System.out.println(s);//打印管道流里面读取到的数据 in.close(); } catch (Exception e) { throw new RuntimeException("管道读取流失败"); } } } class Write implements Runnable { private PipedOutputStream out; Write(PipedOutputStream out){ this.out=out; } public void run() { try { System.out.println("开始写入数据,等待2s.."); Thread.sleep(2000); out.write("zheshishenme".getBytes()); out.close(); } catch (Exception e) { throw new RuntimeException("管道输出流失败"); } } } public class PipedStream { public static void main(String [] args) throws Exception{ PipedInputStream in=new PipedInputStream();//管道读取流 PipedOutputStream out=new PipedOutputStream();//管道输出流 in.connect(out);//把这两个流给接上 Read r=new Read(in); Write w=new Write(out); new Thread(r).start();//这两个线程没有先后顺序,是随机性的 new Thread(w).start(); } }
数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。对于多线程访问不一定是安全的。 线程安全是可选的,它由此类方法的使用者负责。
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /** * 记事本显示的是字符,它对应查字符编码表 * @author hjl * */ public class DataStream { public static void main(String [] args) throws IOException{ writeData(); readData(); readUTFDemo(); writeUTFDemo(); } public static void readUTFDemo()throws IOException{ DataInputStream dis=new DataInputStream(new FileInputStream("uftdate.txt")); String s=dis.readUTF(); System.out.println(s); dis.close(); } public static void writeUTFDemo() throws IOException{ DataOutputStream dos=new DataOutputStream(new FileOutputStream("uftdate.txt")); dos.writeUTF("你好"); dos.close(); } public static void readData() throws IOException{ DataInputStream dis=new DataInputStream(new FileInputStream("data.txt")); int num=dis.readInt(); boolean b=dis.readBoolean(); double d=dis.readDouble(); System.out.println("num="+num); System.out.println("b="+b); System.out.print("d="+d); } public static void writeData() throws IOException{ DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt")); dos.writeInt(234); dos.writeBoolean(true); dos.writeDouble(9888.90877); } }
import java.io.*; /* RandomAccessFile 该类不是算是IO体系中子类。 而是直接继承自Object。 但是它是IO包中成员。因为它具备读和写功能。 内部封装了一个数组,而且通过指针对数组的元素进行操作。 可以通过getFilePointer获取指针位置, 同时可以通过seek改变指针的位置。 其实完成读写的原理就是内部封装了字节输入流和输出流。 通过构造函数可以看出,该类只能操作文件。 而且操作文件还有模式:只读r,,读写rw等。 如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。 如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。 */ class RandomAccessFileDemo { public static void main(String[] args) throws IOException { writeFile_2(); readFile(); } public static void readFile()throws IOException { RandomAccessFile raf = new RandomAccessFile("ran.txt","r"); //调整对象中指针。 //raf.seek(8*1); //跳过指定的字节数 raf.skipBytes(8); byte[] buf = new byte[4]; raf.read(buf); String name = new String(buf); int age = raf.readInt(); System.out.println("name="+name); System.out.println("age="+age); raf.close(); } public static void writeFile_2()throws IOException { RandomAccessFile raf = new RandomAccessFile("ran.txt","rw"); raf.seek(8*0); raf.write("周期".getBytes()); raf.writeInt(103); raf.close(); } public static void writeFile()throws IOException { RandomAccessFile raf = new RandomAccessFile("ran.txt","rw"); raf.write("李四".getBytes()); raf.writeInt(97); raf.write("王五".getBytes()); raf.writeInt(99); raf.close(); } }
import java.io.*; class ByteArrayStream { public static void main(String[] args) { //数据源。 ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes()); //数据目的 ByteArrayOutputStream bos = new ByteArrayOutputStream(); int by = 0; while((by=bis.read())!=-1) { bos.write(by); } System.out.println(bos.size()); System.out.println(bos.toString()); // bos.writeTo(new FileOutputStream("a.txt")); } }