IO流,序列化

JAVA(IO流,序列化)

回顾:

File类不能操作文件的内容

操作文件内容需要IO流(输入输出流)

 

一,IO流

按照流向分

  输入流:从硬盘上读取数据打内存(读)

  输出流:从内存写出数据到硬盘(写)

 

一个文件在传输中经历了多次拷贝,IO性能本身很低

  新技术IO:零拷贝,Nio

按照操作单元分

字节流:按个字节的操作(二进制操作),可操作任意类型文件

字符流:按个字符的操作,一个字符二个字节,主要用来处理文本文件(.txt,.java,.py,.xml,.html,.css,.js)

按照角色划分

节点流:直接操作一个特定的IO设备

处理流:在结点流的基础上,做进一步的处理

 

JAVA中输出/输入常用的流

       字节输入流             字节输出流                 字符输入流  字符输出流

抽象基类  InputStream                OutStream                      Reader      Writer

访问文件  FileInputStream           FileOutputStream           FileReader       FileWriter

(节点流)

缓冲流      BufferedInputStream  BufferedOutputStream   BufferReader    BufferWriter    

(处理流)        

操作对象   ObjectInputStream       ObjectOutputStream  

 

二,流的使用

输入流:

一点一点的往内存读数据

InputStream inputStream =new  FileInputStream("e:\\a.txt");

read方法,返回值int,返回值为-1时,文件读到了末尾

字节流读数据是一个字节一个字节读

一个流读完了就没有了,不能再读

当一个流读完之后会默认调用mark和reset方法进行记录和重置,这个流就重置到上次读完的位置,所以无法再读内容,并不是读完后就关闭

try {
            InputStream inputStream =
                    new FileInputStream("e:\\a.txt");
            int read;
            while ((read = inputStream.read()) != -1){
                System.out.println(read + " ");//
            }
            inputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

 

查看代码
     @Test
    public void test1(){
        try {
            InputStream inputStream =
                    new FileInputStream("e:\\a.txt");
            int read;
            byte[] buf = new byte[10];
            while ((read = inputStream.read(buf)) != -1){
                System.out.println(Arrays.toString(buf) + " ");//
            }
            inputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

 字节输出流

 FileOutputStream构造器

boolean append参数:如果传入true,表示从原有基础加;传入false,或者不传,覆盖原有内容

写的操作,目标文件不存在,会自己加

@Test
    public void teat2(){

        FileOutputStream outputStream = null;
        try {
            outputStream = new
                    FileOutputStream("e:\\a.txt",true);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            outputStream.write("123".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

 

案例:文件复制粘贴

        //文件的复制
        FileInputStream fileInputStream =
                new FileInputStream("e:\\a.txt");
        int read;
        byte[] buf = new byte[10];
        while ((read = fileInputStream.read(buf)) != -1){
            System.out.println(Arrays.toString(buf) + " ");//
        }

        //文件的粘贴
        FileOutputStream fileOutputStream =
                new FileOutputStream("e:a.txt",true);
        fileOutputStream.write(buf,0, buf.length);
        
        fileInputStream.close();

 

复制文件

        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        bufferedReader = new BufferedReader(new FileReader("e:\\a.txt"));
        bufferedWriter = new BufferedWriter(new FileWriter("e:\\b.txt"));

        String str;
        while( (str = bufferedReader.readLine()) != null){
            bufferedWriter.write(str + "\r\n");
        }
        bufferedReader.close();
        bufferedWriter.close();

 

三,序列化与反序列化

(操作对象)

序列化:将对象写入到IO流中,将内存模型的对象变成字节数字,可以进行存储和传输

反序列化:从IO流中恢复对象,将存储在硬盘上或者从网络中接受的数据恢复成对象模型

使用场景:所有可在网络上 传输的对象都必须是可序列化的,否则报错,所有保存在硬盘上的对象也必须可序列化

 

序列化版本号:

反序列化必须拥有class文件,但随着项目的升级,class文件也会升级;序列化需保证升级前后的兼容性

java序列化提供了一个版本号,可以自己指定,如果不指定,jvm会根据类信息计算一个版本号,所以无法匹配,则报错

不指定版本号,不利于jvm的移植,可能class文件没有改,但不同jvm计算规则不一样,导致无法反序列化

如果只修改方法,反序列化是不受影响的,无需修改版本号

修改了静态变量static,瞬态变量transient,反序列化也不受影响,无需修改版本号

 

所有需要网络传输的对象需要实现序列化接口

对象的类名,实例变量都会被序列化;方法和类变量,transient变量不会被序列化

想让某对象不被序列化,可用transient修饰

序列化对象的引用类型成员变量,也必须是可序列化的,否则会报错

反序列化时必须有序列化对象的class文件

同一个对象被序列化多次,只有第一次序列化为二进制流,以后都只保存序列化的版本号

建议所有可序列化的类加上版本号,方便项目升级

 

 //读取db.properties文件
Properties properties = new Properties();
        properties.load(new FileInputStream("db.properties"));
        System.out.println(properties.getProperty("name"));

 

posted @ 2022-08-09 14:36  一只神秘的猫  阅读(35)  评论(0)    收藏  举报