IO流(下)

 

PrintStream

  打印流 ---- PrintStream

  底层是字节流 ----- 输出

  System.out和System.err都是由打印流创建的对象

import java.io.IOException;
import java.io.PrintStream;
​
public class PrintStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建一个打印流对象  
        PrintStream ps = new PrintStream("D:\\a.txt");
        
        //打印数据 --- 字节流 ---- 往外写出数据
        ps.write("ADF".getBytes());
        
        //打印任何类型的数据
        ps.print(true);
        ps.println("ANFD");
        ps.print("41321");
        
        //关流
        ps.close();
    }
}

 

合并流(SequenceInputStream)

都是字节输入流,不会存在字节输出

在合并的时候要注意其他输入流的编码以及格式是否统一

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
​
public class SequenceInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //其他的字节输入流对象
        FileInputStream in1 = new FileInputStream("D:\\a.txt");
        FileInputStream in2 = new FileInputStream("D:\\b.txt");
        FileInputStream in3 = new FileInputStream("D:\\c.txt");
        
        //创建Vector对象,把输入流放在Vector上
        Vector<FileInputStream> v = new Vector<FileInputStream>();
        v.add(in1);
        v.add(in2);
        v.add(in3);
        
        //通过Vector对象调用迭代器
        Enumeration<FileInputStream> e = v.elements();
        
        //把这个对象放到合并流用于创建合并流对象
        SequenceInputStream sis = new SequenceInputStream(e);
        
        //创建一个输出流,用于储存放合并之后的结果
        FileOutputStream os = new FileOutputStream("D:\\f.txt");
        
        //读取流中的内容进行合并
        byte[] bs = new byte[10];
        int len =-1;
        while((len=sis.read(bs))!=-1){
            //写出数据
            os.write(bs,0,len);
        }
        
        //关流,正常情况从内往外关
        //直接关掉最外层
        sis.close();
        sis=null;
    }
}

 

双向流(RandomAccess)

  可以指定模式进行读取

  底层数基于数组,所有可以通过改变下标进行读取的操作,在操作的时候要注意下标值的情况

import java.io.IOException;
import java.io.RandomAccessFile;
​
public class RandomAccessDemo {
    public static void main(String[] args) throws IOException {
        //创建双向流对象----指定访问模式(支持读和写)
        RandomAccessFile raf = new RandomAccessFile("D:\\a.txt", "rw");
        
        //写出数据
        raf.write("hello".getBytes());
        
        //指定下标 ----- 从0开始的下标
        raf.seek(0);
        
        //读取数据
        System.out.println((char)raf.read());
        
        //指定下标
        raf.seek(3);
        raf.write("WW".getBytes());
        System.out.println((char)raf.read());
        
        //关流
        raf.close();
        
    }
}
​

 


 

 

流的序列化,反序列化

序列化:把对象相关的信息转成字节进行存储(如果最终存储的地方是硬盘 ------ 持久化)
反序列化:把字节转化成对象

 

注意:要序列化的对象对应的类要实现Serializable接口

可以传多个对象

静态属性不能序列化,静态属性与类同级

被transient修饰的属性不能序列化

方法不会被序列化

集合,映射不能被直接序列化,要将其中的元素进行遍历依次进行序列化

应用场景:网络和服务器进行数据交互(场景)

Person类:

import java.io.Serializable;
​
public class Person implements Serializable{
    
/**
     * java自动提示
     */
    private static final long serialVersionUID = -8923458557770938902L;
    
    private String name;
    private int age;
    //静态属性,不能序列化
    static String classroom;
    //被transient修饰的属性不能序列化
    transient double height;
    //体重
    double weight;
    
    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 "Person [name=" + name + ", age=" + age + "]";
    }
    
}
​

 

ObjectInputStream&&ObjectOutputStream

ObjectOutputStreamDemo:序列化
import java.io.FileNotFoundException; 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
​
public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws FileNotFoundException, IOException{
        //创建一个Person类的对象
        Person p = new Person();
        //给对象属性赋值
        p.setAge(20);
        p.setName("lili");
        
        Person p1 = new Person();
        p1.setAge(30);
        p1.setName("sanzai");
        //把对象转成字节进行存储
        //指定对象转完字节之后存储的位置
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\a.data"));
        
        //写出对象
        oos.writeObject(p);
        oos.writeObject(p1);
        //关流
        oos.close();
        
    }
}

 

ObjectInputStream:反序列化
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
​
​
public class ObjectinputStreamDemo {
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException{
        
        //创建一个反序列化的对象
        //指定要反序列化的文件
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\a.data"));
        
        //获取对象
        Person p = (Person) ois.readObject();
        Person p1 = (Person) ois.readObject();
        //关流
        ois.close();
        
        //展示对象的信息
        System.out.println(p.getAge());     //20
        System.out.println(p.getName());    //lili
        System.out.println(p1.getAge());    //30
        System.out.println(p1.getName());   //sanzai
    }
}

 

serialVersionUID:

序列化的版本号:当要序列化的对象以及实现Serializeable接口,java就会根据这个对象对应的类里的属性和方法计算出一个值-----版本号(serialVersionUID),这个版本号会随着对象的序列化而一起序列化出去,当要进行反序列化的时候会根据序列化出去的版本号回于当前对象的序列号进行比较,如果相等序列化才能成功

解决上述问题,添加一个版本号的定值被(private static final long)修饰

posted @ 2020-08-19 11:46  minnersun  阅读(107)  评论(0)    收藏  举报