Java I/O流

1.IO流,什么是IO?

I : Input
O : Output
通过IO可以完成硬盘文件的读和写。
在这里插入图片描述

一.IO流的分类?

有多种分类方式:

一种方式是按照流的方向进行分类:
以内存作为参照物,
往内存中去,叫做输入(Input)。或者叫做读(Read)。
从内存中出来,叫做输出(Output)。或者叫做写(Write)。

另一种方式是按照读取数据方式不同进行分类:
有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。
这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件等…
假设文件file1.txt,采用字节流的话是这样读的:
a中国bc张三fe
第一次读:一个字节,正好读到’a’
第二次读:一个字节,正好读到’中’字符的一半。
第三次读:一个字节,正好读到’中’字符的另外一半。

有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取
普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯
文本文件,连word文件都无法读取。
假设文件file1.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读:'a’字符('a’字符在windows系统中占用1个字节。)
第二次读:'中’字符('中’字符在windows系统中占用2个字节。)

综上所述:流的分类
输入流、输出流
字节流、字符流
在这里插入图片描述
在这里插入图片描述
最后一行这个输出流画错了 FileOutStream
通过这个图方便理解
重点理解

  1. String filePath = "e:\\news1.txt"; File file = new File(filePath); 我们这里可以这么理解就是 file对象就是我们内存中的对象 也就是抽象文件和我们这个真实硬盘上的txt文件进行相互绑定
  2. 在这里插入图片描述
    FileInputStream file=null; file=new FileInputStream("D:\\Study\\Java\\Test\\wtf.txt"); 我们可以不用创建抽象文件 直接使用字符串路径名进行查找硬盘上的文件 这里就是通过流对象去操作txt文件对象 也就是将磁盘的文件放入流放对象中也就是放入管道中
    同理fileoutputStream则是将管道中的文件放入要放入的地方这里指的是demo.txt
  3. byte 我们所谓的byte数据或byte数组就是中间图示的缓冲区
    流对象的read方法会一直往下读取 就是好像默认有个next
  4. 序列化 ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(".vscode\\oos.class")); 就是操作流对象就是对管道进行操作 将管道输出流中的文件放入以序列化格式二进制字节码硬盘中
  5. 反序列化就是将硬盘的管道对象操作 ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(".vscode\\oos.class")); //通过返回序列化 ,从objectInputStream 中将对象序列化数据读取到一个对象 Object obj=objectInputStream.readObject();

二.java IO流这块有四大家族:

四大家族的首领:
java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
四大家族的首领都是抽象类。(abstract class)
所有的流都实现了:
java.io.Closeable接口,都是可关闭的,都有close()方法。
流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,
不然会耗费(占用)很多资源。养成好习惯,用完流一定要关闭。
所有的输出流都实现了:
java.io.Flushable接口,都是可刷新的,都有flush()方法。
养成一个好习惯,输出流在最终输出之后,一定要记得flush()
刷新一下。这个刷新表示将通道/管道当中剩余未输出的数据
强行输出完(清空管道!)刷新的作用就是清空管道。
注意:如果没有flush()可能会导致丢失数据。
注意:在java中只要“类名”以Stream结尾的都是字节流。以“Reader/Writer”结尾的都是字符流。

三.FileInputStream

主要方法介绍:
void close()
关闭此输入流并释放与该流关联的所有系统资源。
abstract int read()
从输入流读取下一个数据字节。
int read(byte[] b)
public int read(byte[] b)
throws IOException
从输入流读取一些字节数,并将它们存储到缓冲区b 。 实际读取的字节数作为整数返回。 该方法阻塞直到输入数据可用,检测到文件结束或抛出异常。
区数组 b 中。
public void write(byte[] b)
throws IOException
将b.length字节从指定的字节数组写入此输出流。 write(b)的一般合约是应该具有与电话write(b, 0, b.length)完全相同的效果。
public int read(byte[] b,
int off,
int len)
throws IOException
从输入流读取len字节的数据到一个字节数组。 尝试读取多达len个字节,但可以读取较小的数字。 实际读取的字节数作为整数返回。
该方法阻塞直到输入数据可用,检测到文件结束或抛出异常。

1.初步

java. io FileInputstream:
1、文件字节输入流,万能的,任何类型的文件部可以采用这个流来读。
2、宇节的方式,完成输入的操作,完成读的操作(硬盘-)内存

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream file=null;
        try {
            //创建文件字节输入流对象
         file=new FileInputStream("D:\\Study\\Java\\Test\\wtf.txt");
/*            while (true){
                int data=file.read();
                if(data == -1)
                    break;
                System.out.println(data);
            }*/
            //改进while
            int data=0;
            while ((data=file.read())!=-1){
                System.out.println(data);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //在finally语句块确保流一定关闭
            if (file != null) {//避免空指针异常
                //关闭流的前提是:流不是空.流是null的时候没必要关闭
                try {
                    file.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

97
98
99
32(空格)
100
101
102
-1

2.往byte数组中读

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream file=null;
        try {
            file=new FileInputStream("D:\\Study\\Java\\Test\\wtf.txt");
            //开始读,采用byte数组,一次取多个字节。最多读取"数组.length"个字节。
            byte[] bytes=new byte[4];//准备一个个长度的byte数组,一次最多读取4个字。
            //这个方法的返回值是:读取到的字节数量。(不是字节本身)
            int readcount= file.read(bytes);
            System.out.println(readcount);//第一次读到了4个字节。
            //将字节数组全部转换成字符串
            //System.out.println(new String(bytes));// abcd
            //不应该全部部转换,应该是读取了多少个字节,转换多少个。
            System.out.println(new String(bytes,0,readcount));

            readcount= file.read(bytes);//第二次只能读取到2个字节
            System.out.println(readcount);//2
            //将字节数组全部转换成字符串
            //System.out.println(new String(bytes));// efcd
            //不应该全部部转换,应该是读取了多少个字节,转换多少个。
            System.out.println(new String(bytes,0,readcount));
             readcount= file.read(bytes);//1个字节都没到返回-1
            System.out.println(readcount);//-1
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (file != null) {
                try {
                    file.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

4
abcd
2
ef
-1

3.最终版

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream file=null;
        try {
            file=new FileInputStream("D:\\Study\\Java\\Test\\wtf.txt");
            byte[] bytes=new byte[4];//准备一个个长度的byte数组,一次最多读取4个字。
/*            while (true){
                int readcount=file.read(bytes);
                if (readcount==-1){
                    break;
                }
                System.out.print(new String(bytes,0,readcount));
            }*/
            //极致优化
            int readcount=0;
            while (( readcount=file.read(bytes)) !=-1){
                System.out.print(new String(bytes,0,readcount));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (file != null) {
                try {
                    file.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

abcdef

4.FileInputStream的其他方法

FileInputstream类的其它常用方法:
int available():返回流当中剩余的没有到的字节数量
Long skip( Long n):跳过几个字节不读。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamTest05 {
    public static void main(String[] args) {
        FileInputStream fis=null;
        try {
            fis=new FileInputStream("D:\\Study\\Java\\Test\\wtf.txt");
            System.out.println("总字节数量"+fis.available());
/*          读1个字节
            int readByte = fis.read();
            还剩下可以峡的字节数量是:5
            System.out.println("剩下多少个字节没有读:"+fis. available());
                /这个方法有什么用?*/
            int data=fis.read();
            System.out.println("剩下多少个字节没读"+fis.available());
            //这种方式不太适合太大的文件,因为byte[]数组不能太大
            byte[] bytes=new byte[fis.available()];
            //不需要循环了
            //直接测一次就行了
            int readCount=fis.read(bytes);
            System.out.println(new String(bytes));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis == null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

总字节数量6
剩下多少个字节没读5
bcdef

5.FileOutStream

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamTest01 {
    public static void main(String[] args) {
        FileOutputStream files=null;
        try {
/*
 myfile.文件不存在的时候会自动新建!
这种方式谨算使用,这种方式会先将原文件清空,然后重新写入。
 files new FileoutputStream ("myfile")*/

            //这种方式在末尾添加
            //以追加的方式在文件末尾写入,不会清空原文件内容
         files=new FileOutputStream("myfile",true);
            //开始写
            byte[] bytes={97,98,99,100};
            //将byte数组全部写出
            files.write(bytes);//abcd
            //将byte数组一部分写出
            files.write(bytes,0,2);//再写出ab
            //字符串转换为byte数组
            String s="我是一整个";
            byte[] bs=s.getBytes();
            files.write(bs);
            //写出之后,最后一定要刷新
            files.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (files != null) {
                try {
                    files.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

abcdab我是一整个

6.文件拷贝

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Copy01 {
    public static void main(String[] args) {
        FileInputStream fies=null;
        FileOutputStream foS =null;
        try {
            fies=new FileInputStream("D:\\Study\\Java\\Test\\wtf.txt");
            foS=new FileOutputStream("D:\\Study\\Java\\wtf.txt");
            byte[] bytes=new byte[1024*1024];
            int readCount=0;
            while ((readCount = fies.read(bytes))!=-1){
                foS.write(bytes,0,readCount);
            }
            foS.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //分开try,不要在一起try
            //一起try的时候,其中一个出现异常,可能影响到另一个流的关系
            if (foS == null) {
                try {
                    foS.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fies == null) {
                try {
                    fies.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

三.FileReader和FileWriter

区别,以字符char[] 代替byte[],以一字符代替一字节
i

mport java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/*FileReader
        文件字符输入流,只能读取普通文本。
        读取文本内容时,比较方便,快捷。*/
public class FileReaderTest {
    public static void main(String[] args) {
        FileReader reader=null;
        try {
            reader =new FileReader("myfile");
        /*    char[] chars=new char[4];
            int readCount=0;
            while((readCount=reader.read(chars))!=-1){
                System.out.print(new String(chars,0,readCount));
            }*/
            char[]  chars=new char[4];
            reader.read(chars);
            for (char c:chars){
                System.out.print(c);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader == null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

abcd

import java.io.FileWriter;
import java.io.IOException;

public class FileWrite {
    public static void main(String[] args) {
        FileWriter out=null;
        try {
            out=new FileWriter("fils");
            char[] chars={'我','是','中','国','人'};
            out.write(chars);
            out.write(chars,1,2);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (out == null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

我是中国人是中

四.节点流和包装流

import java.io.*;
public class BufferedReaderTest02 {
    public static void main(String[] args) throws IOException {
/*
        //字节流
        FileInputStream file=new FileInputStream("myfile");

        通过转换流转换( InputstreamReader将字节流转换成字符流。)
        in是节点流。 reader是包装流。
        InputStreamReader in=new InputStreamReader(file);
        这个构造方法只能传一个字符流。不能传字节流。
        reader是点流。b是包装流。
        BufferedReader br=new BufferedReader(in);*/
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("myfile")));
        String s=null;
        while ((s=br.readLine())!=null){
            System.out.print(s);
        }
        br.close();

    }
}

abcdab我是一整个abcdab我是一整个abcdab我是一整个assdaasg

五.带有缓冲区的字符流

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderTest01 {
    public static void main(String[] args) throws IOException {
        FileReader reader=new FileReader("myfile");
        //当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流。
//外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流。
//像当前这个程序来说: Filereader就是一个节点流。 BufferedReader就是包装流/处理流。
        BufferedReader br=new BufferedReader(reader);
/*        String firstLine=br.readLine();
        System.out.println(firstLine);
        String secondLine=br.readLine();
        System.out.println(secondLine);*/
        String  s=null;
        while((s=br.readLine())!=null){
            System.out.print(s);
        }
    }
}

六.数据流

import java.io.DataOutputStream;
import java.io.FileOutputStream;
/*java.io. DataOutputstream:数据专属的流。
        这个流可以数据连同数据的类型一并写入文件。
        注意:这个文件不是普通文本文档。(这个女件使用记事本打不开。)*/
public class DateOutputStreamTest {
    public static void main(String[] args) throws Exception {
        DataOutputStream dos=new DataOutputStream(new FileOutputStream("data"));
        byte b=100;
        short s=200;
        int i=1;
        long l=400L;
        float f=3.0f;
        double d=3.14;
        boolean sex=false;
        char c='f';
        dos.writeByte(b);
        dos.writeShort(s);
        dos.writeInt(i);
        dos.writeLong(l);
        dos.writeFloat(f);
        dos.writeDouble(d);
        dos.writeBoolean(sex);
        dos.writeChar(c);
        //刷新
        dos.flush();

        dos.close();
    }
}
import java.io.DataInputStream;
import java.io.FileInputStream;
/*
DataInputstream:数据字节输入流。
DataOutputstream写的文件,只能使用 DataInputstream去读。
并且的时候你需要提前知道写入的顺序。
读的顺序需要和写的顺序一致。才可以正常取出数据。*/
public class DateInputStreamTest {
    public static void main(String[] args)throws Exception {
        DataInputStream dis=new DataInputStream(new FileInputStream("data"));
        byte b=dis.readByte();
        short s=dis.readShort();
        int i=dis.readInt();
        long l=dis.readLong();
        float f=dis.readFloat();
        double d=dis.readDouble();
        boolean sex=dis.readBoolean();
        char c=dis.readChar();

        System.out.println(b);
        System.out.println(s);
        System.out.println(i);
        System.out.println(l);
        System.out.println(f);
        System.out.println(d);
        System.out.println(sex);
        System.out.println(c);
        dis.close();
    }
}

200
1
400
3.0
3.14
false
f

七.标准输出流

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class PrintStreamTest {
    public static void main(String[] args) throws FileNotFoundException {
        //联合起来写
        System.out.println("hello world");
        //分开写
        PrintStream ps=System.out;
        ps.println("hello zhangsan");
        ps.println("hello lisi");
        ps.println("hello wangwu");
      /*标准输出流不需要手动 close()关闭
        可以改交标准输出流的输出方向吗?可以
      /这些是之前System类使用过的方法和属性。
        System gc();
        System.currentTimeMillis();
        Printstream ps2= System.out;
        System.exit(0);
        System.arraycopy(....)*/
        //标准输出流不再指向控制台,指向"log"文件
        PrintStream printStream=new PrintStream(new FileOutputStream("log"));
        //修改输出方向,将输出方向修改到"log"文件
        System.setOut(printStream);
        printStream.println("fuck");
        printStream.println("shift");
        printStream.println("I");
        printStream.println("can");
        printStream.println("win");
    }
}

fuck
shift
I
can
win

2.File类的理解

File
1、File类和四大家族没有关系,所以File类不能完成文件的读和写
2、File对象代表什么?
文件和日录路径名的抽泉表示形式。
C:\ Drivers这是一个File对象
C:\Drivers\Lan\Realtek\ Readme.txt也是File对象
个让File对有可能对应的是目录,也可能是文件。
File只是一个路径名的抽象表示形式
3、需要掌握File类中常用的方法

File常用方法Test

import java.io.File;
import java.io.IOException;

public class FileTest01 {
    public static void main(String[] args) throws IOException {
        //创建file对象
        File f1=new File("D:\\Study\\Java\\file");
        //判断是否存在!
        System.out.println(f1.exists());
        //如果D:\Study\Java\file不存在,则以文件的形式创建出来
/*        if (!f1.exists()){
        //以文件形式新建
            f1.createNewFile();
        }*/
        //以目录形式创建
        if(!f1.exists()){
            f1.mkdir();
        }
        File f3=new File("D:\\Study\\Java\\wtf.txt");
        //获取文件父路径
        String parentParent=f3.getParent();
        System.out.println(parentParent);
        //获取绝对路径
        File parentFile=f3.getParentFile();
        System.out.println("获取绝对路径"+parentFile.getAbsolutePath());
    }

}

true
D:\Study\Java
获取绝对路径D:\Study\Java

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileTest02 {
    public static void main(String[] args) {
          File f1=new File("D:\\Study\\Java\\wtf.txt");
          //获取文件名
        System.out.println(f1.getName());

        //判断是否是一个目录
        System.out.println(f1.isFile());

        //判断是否是一个文件
        System.out.println(f1.isDirectory());

        //获取文件最后一次修改时间
        long haoMiao=f1.lastModified(); //这个毫秒是从1970年到现在的总毫秒数
        //将毫秒数转换成日期
        Date time=new Date(haoMiao);
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        String strTime=sdf.format(time);
        System.out.println(strTime);

        //获取文件大小
        System.out.println(f1.length());
    }
}

wtf.txt
true
false
2021-02-24 15:49:08 313
6

import java.io.File;

public class FileTest03 {
    public static void main(String[] args) {
        //File[] listFiles()
        //获取当前录下所有的子文件
        File f=new File("D:\\Study\\Java");
        File[] files=f.listFiles();
        for (File file:files){
            System.out.println(file.getAbsolutePath());
        }
    }
}

D:\Study\Java\02-JavaSE零基础每日复习与笔记
D:\Study\Java\07-JavaSE进阶每日复习与笔记
D:\Study\Java\08-JavaSE进阶讲义
D:\Study\Java\09-JavaSE进阶每章课堂画图

对象流

ObjectInputStream
ObjectOutputStream

重点:
	参与序列化的类型必须实现java.io.Serializable接口。
	并且建议将序列化版本号手动的写出来。
		private static final long serialVersionUID = 1L;

在这里插入图片描述

Student类
package com.bjpowernode.java.bean;

import java.io.Serializable;

public class  Student implements Serializable {

    // IDEA工具自动生成序列化版本号。
    //private static final long serialVersionUID = -7998917368642754840L;

    // Java虚拟机看到Serializable接口之后,会自动生成一个序列化版本号。
    // 这里没有手动写出来,java虚拟机会默认提供这个序列化版本号。
    // 建议将序列化版本号手动的写出来。不建议自动生成
    private static final long serialVersionUID = 1L; // java虚拟机识别一个类的时候先通过类名,如果类名一致,再通过序列化版本号。

    private int no;
    //private String name;

    // 过了很久,Student这个类源代码改动了。
    // 源代码改动之后,需要重新编译,编译之后生成了全新的字节码文件。
    // 并且class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生相应的改变。
    private int age;
    private String email;
    private String address;

    public Student() {
    }

    public Student(int no, String name) {
        this.no = no;
        //this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    /*public String getName() {
        return name;
    }*/

    /*public void setName(String name) {
        this.name = name;
    }*/

    /*@Override
    public String toString() {
        return "Student{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }*/

    @Override
    public String toString() {
        return "Student{" +
                "no=" + no +
                ", age=" + age +
                ", email='" + email + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

序列化

package com.bjpowernode.java.io;

import com.bjpowernode.java.bean.Student;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

/*
1、java.io.NotSerializableException:
    Student对象不支持序列化!!!!

2、参与序列化和反序列化的对象,必须实现Serializable接口。

3、注意:通过源代码发现,Serializable接口只是一个标志接口:
    public interface Serializable {
    }
    这个接口当中什么代码都没有。
    那么它起到一个什么作用呢?
        起到标识的作用,标志的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。
        Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到这个接口之后,会为该类自动生成
        一个序列化版本号。

4、序列化版本号有什么用呢?
    java.io.InvalidClassException:
        com.bjpowernode.java.bean.Student;
        local class incompatible:
            stream classdesc serialVersionUID = -684255398724514298(十年后),
            local class serialVersionUID = -3463447116624555755(十年前)

    java语言中是采用什么机制来区分类的?
        第一:首先通过类名进行比对,如果类名不一样,肯定不是同一个类。
        第二:如果类名一样,再怎么进行类的区别?靠序列化版本号进行区分。

    小鹏编写了一个类:com.bjpowernode.java.bean.Student implements Serializable
    胡浪编写了一个类:com.bjpowernode.java.bean.Student implements Serializable
    不同的人编写了同一个类,但“这两个类确实不是同一个类”。这个时候序列化版本就起上作用了。
    对于java虚拟机来说,java虚拟机是可以区分开这两个类的,因为这两个类都实现了Serializable接口,
    都有默认的序列化版本号,他们的序列化版本号不一样。所以区分开了。(这是自动生成序列化版本号的好处)

    请思考?
        这种自动生成序列化版本号有什么缺陷?
            这种自动生成的序列化版本号缺点是:一旦代码确定之后,不能进行后续的修改,
            因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候java
            虚拟机会认为这是一个全新的类。(这样就不好了!)

    最终结论:
        凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号。
        这样,以后这个类即使代码修改了,但是版本号不变,java虚拟机会认为是同一个类。

 */
public class ObjectOutputStreamTest01 {
    public static void main(String[] args) throws Exception{
        // 创建java对象
        Student s = new Student(1111, "zhangsan");
        // 序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("students"));

        // 序列化对象
        oos.writeObject(s);

        // 刷新
        oos.flush();
        // 关闭
        oos.close();
    }
}

反序列化

package com.bjpowernode.java.io;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

/*
反序列化
 */
public class ObjectInputStreamTest01 {
    public static void main(String[] args) throws Exception{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("students"));
        // 开始反序列化,读
        Object obj = ois.readObject();
        // 反序列化回来是一个学生对象,所以会调用学生对象的toString方法。
        System.out.println(obj);
        ois.close();
    }
}

list集合在java276 277教程中有提到

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值