(黑马程序员)学习笔记,其他IO流对象

来源:互联网 发布:淘宝卖家设置产品折扣 编辑:程序博客网 时间:2024/05/17 20:00

1. ObjectInputStream和ObjectOutputStream

package io;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;/** * 1、序列化是干什么的?  简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存Object States,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。2、什么情况下需要序列化 a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;b)当你想用套接字在网络上传送对象的时候;c)当你想通过RMI传输对象的时候;3、当对一个对象实现序列化时,究竟发生了什么?在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实例变量(instance ariable)比如:Foo myFoo = new Foo(); myFoo .setWidth(37); myFoo.setHeight(70);   当通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(37,70)都被保存到foo.ser文件中,这样以后又可以把它 从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对 象。FileOutputStream fs = new FileOutputStream("foo.ser"); ObjectOutputStream os = new ObjectOutputStream(fs); os.writeObject(myFoo); 4、实现序列化(保存到一个文件)的步骤a)Make a FileOutputStream java 代码FileOutputStream fs = new FileOutputStream("foo.ser"); b)Make a ObjectOutputStream java 代码ObjectOutputStream os = new ObjectOutputStream(fs); c)write the objectjava 代码os.writeObject(myObject1); os.writeObject(myObject2); os.writeObject(myObject3); d) close the ObjectOutputStreamjava 代码os.close(); 5、举例说明java 代码import java.io.*; public class Box implements Serializable { private int width; private int height; public void setWidth(int width){ this.width = width; } public void setHeight(int height){ this.height = height; } public static void main(String[] args){ Box myBox = new Box(); myBox.setWidth(50); myBox.setHeight(30); try{ FileOutputStream fs = new FileOutputStream("foo.ser"); ObjectOutputStream os = new ObjectOutputStream(fs); os.writeObject(myBox); os.close(); }catch(Exception ex){ ex.printStackTrace(); } } } 6、相关注意事项a)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;b)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;c)并非所有的对象都可以序列化,,至于为什么不可以,有很多原因了,比如:  1.安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输 等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。  2. 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分 配,而且,也是没有必要这样实现。 * @author asus * */public class ObjectStreamDemo {public static void main(String[] args) {try {writeObj();readObj();} catch (Exception e) {e.printStackTrace();}}private static void writeObj() throws IOException{ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("E:\\BaiduYunDownload\\FILE\\obj")));oos.writeObject(new Person("test",99));oos.close();}private static void readObj() throws IOException, ClassNotFoundException{ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("E:\\BaiduYunDownload\\FILE\\obj")));Person p = (Person)ois.readObject();System.out.println(p.toString());ois.close();}}//序列化class Person implements Serializable{//手动匹配序列号private static final long serialVersionUID = 42L;private String name;private int age;Person(String name,int age){this.name = name;this.age = age;}public String toString(){return name+".."+age;}}

2. PipedInputStream 和PipedOutputStream

package io;import java.io.IOException;import java.io.PipedInputStream;import java.io.PipedOutputStream;/* * 管道流对象 PipedInputStream PipedOutputStream,输入输出可以直接连接的特殊流对象,应该通过多线程使用以免死锁。 */public class PipedStreamDemo {public static void main(String[] args) {//创建管道流对象PipedInputStream in = new PipedInputStream();PipedOutputStream out = new PipedOutputStream();try {//将输入输出管道流连接in.connect(out);//将管道流添加到多线程中Read r = new Read(in);Writer w = new Writer(out);//创建线程Thread tr = new Thread(r);Thread tw = new Thread(w);//开启线程tr.start();tw.start();} catch (IOException e) {e.printStackTrace();}}}class Read implements Runnable{private PipedInputStream pipIn;//通过构造函数传入PipedInputStream对象public Read(PipedInputStream pipIn){this.pipIn = pipIn;}public void run() {try {//读取数据byte[] buf = new byte[1024];int len = pipIn.read(buf);String s = "没有数据";if(len!=-1){s = new String(buf,0,len);}System.out.println(s);} catch (IOException e) {throw new RuntimeException("管道流读取失败");}finally{if(pipIn!=null){try {pipIn.close();} catch (IOException e) {e.printStackTrace();}}}}}class Writer implements Runnable{private PipedOutputStream pipOut;public Writer(PipedOutputStream pipOut){this.pipOut = pipOut;}public void run() {try {//写入数据pipOut.write("管道TEST".getBytes());} catch (IOException e) {throw new RuntimeException("管道流输出失败");}finally{if(pipOut!=null){try {pipOut.close();} catch (IOException e) {e.printStackTrace();}}}}}

3. RandomAccessFile

package io;import java.io.IOException;import java.io.RandomAccessFile;/* * RandomAccessFile *  * 该类不是IO体系中的子类,而是直接继承自Object * 既能读又能写,封装了数组和指针 *  * 但是他是IO包中的成员,因为它具备读和写功能,内部封装了一个数组,而且通过指针对数组中的元素进行操作 * 可以通过getFilePointer获取指针位置,同时通过seek改变指针的位置 *  * 内部封装了字节输入输出流,该类只能操作文件,并且还有操作模式:只读"r" 读写"rw" * 如果模式为"r",不会创建文件,只读取已存在的文件,如果文件不存在,则出现异常。 * 如果模式为"rw",操作文件不存在,会自动创建文件。 */public class RandomAccessFileDemo {public static void main(String[] args) {String dir = "E:\\BaiduYunDownload\\FILE";try {writeFile(dir);System.out.println("数据已输出");readFile(dir);} catch (IOException e) {e.printStackTrace();}}private static void writeFile(String dir) throws IOException{//创建RandomAccessFile对象,设置读写模式RandomAccessFile raf = new RandomAccessFile(dir+"\\raf.txt", "rw");//写入raf.write("张三".getBytes());raf.writeInt(65);raf.write("李四".getBytes());raf.writeInt(97);raf.close();}private static void readFile(String dir) throws IOException{RandomAccessFile raf = new RandomAccessFile(dir+"\\raf.txt", "r");//调整指针raf.seek(4*2);//读取四个字节byte[] buf = new byte[4];int len = raf.read(buf);String s = "";if(len!=-1){s = new String(buf,0,len);}System.out.println(s);raf.close();}}

4. DataInputStream 和 DataOutputStream

package io;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;/* * 用于操作基本类型的数据流对象 */public class DataStreamDemo {public static void main(String[] args) {String dir = "E:\\BaiduYunDownload\\FILE";try {writeDataUTF(dir);//readData(dir);//用转换流的方法,输出utf-8编码的字符流OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(new File(dir+"\\osw.txt")),"utf-8");osw.write("测试");osw.close();readDataUTF(dir);System.out.println("完成");} catch (IOException e) {e.printStackTrace();}}//使用utf-8改版字符码表来输出数据,输出后只能使用readUTF()来读取private static void writeDataUTF(String dir) throws IOException{DataOutputStream dos = new DataOutputStream(new FileOutputStream(dir+"\\dosUTF.txt")); dos.writeUTF("测试");dos.close();}//使用utf-8改版字符码表来读取数据private static void readDataUTF(String dir) throws IOException{DataInputStream dis = new DataInputStream(new FileInputStream(dir+"\\dosUTF.txt"));String s = dis.readUTF();System.out.println("字符串:"+s);dis.close();}//输出基本类型数据private static void writeData(String dir) throws IOException{DataOutputStream dos = new DataOutputStream(new FileOutputStream(dir+"\\dos.txt")); dos.writeInt(423);dos.writeBoolean(true);dos.writeDouble(11.22);dos.close();}//按着顺序读取基本数据类型数据private static void readData(String dir) throws IOException{DataInputStream dis = new DataInputStream(new FileInputStream(dir+"\\dos.txt")); int num = dis.readInt();boolean b = dis.readBoolean();double d = dis.readDouble();System.out.println("数字:"+num+"\n"+"布尔:"+b+"\n"+"小数:"+d+"\n");dis.close();}}

5. ByteArrayInputStream 和 ByteArrayOutputStream

package io;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;/* * 用于操作字节数组的流对象 *  * ByteArrayInputStream:构造时需要接收数据源,而且数据源是一个字节数组。 * ByteArrayInputStream:构造时不需要定义数据源,而是在内部封装了一个可变长度的字节数组。 *  * 因为两个流对象都操作数组,并没有使用系统资源,所以不用关闭。 *  * 跟它类似的还有:字符数组流CharArrayReader、ChararrayWriter  * 字符串流 StringReader、StringWriter */public class ByteArrayStreamDome {public static void main(String[] args) {//数据源byte[] buf = "ABCDEFG".getBytes();ByteArrayInputStream in = new ByteArrayInputStream(buf);//数据目的ByteArrayOutputStream out = new ByteArrayOutputStream();int len = 0;while((len=in.read())!=-1){out.write(len);}System.out.println(out.toString());}}


0 0