I/O流概要整理

1、I/O流简介
1.I/O流概念
①I/O: Input(输入) / Output(输出) 的缩写。
②流:可以理解为在计算机中两个不同位置之间建立的一个通道,该通道用于传输数据。
③I/O流:则可以理解为: 数据输入 和 数据输出 的通道。(可以想象成自来水管道运水,水理解成数据 ,水管道理解成流)。
2.I/O流的大致分类
背景:
在现实生活中,家中自来水管道根据水流的方向:有进水管道、出水管道之分。对于不同场景位置管道的类型也不同。
如:城市用水管道很大,家中自用的管道因为水流量较小,口径就相对较小。
同理,在计算机中使用的I/O流,根据数据传输方向、传输量等情况的不同,也有相对应的不同应流进行处理。
大致分类:
①按流向分(站在java程序所在位置的角度):Input 【输入流】 、Output【输出流】
②按传输的数据类型分:
字节流(InputStream 、OutputStream) :以字节为单位进行数据传输,任何文件都可以通过字节流进行传输。
字符流(Reader 、Writer): 以字符为单位进行数据的传输,对于字符串数据的传输效率高、速度快。
注:(视频、音乐、图片等数据因为底层是字节,所以这类非文本数据不能使用字符流传输,应该使用字节流。
字符流和字节流,最最底层的传输其实都是字节。)
③按功能分:
节点流(低级流:向一个特定的地方写入(或读取)数据。)
FileInputStream、FileOutputStream、FileReader、FileWriter、PrintStream、PrintWriter等等流都是节点流。
处理流(高级流:在低级流的基础上,对流进行连接或操作,这类流的构造方法()中基本都可以传入低级流对象作为参数)
如:转换流:InputStreamReader、OutputStreamWriter,等;
缓冲流:BufferedInputStream/BufferedOutputStream BufferedReader/BufferedReader可对节点流包装,使读写更快。
3.【Input 输入流】、【Output 输出流】的使用场景问题
①首要概念:【输入】和【输出】的参照位置都是 java程序当前运行时所在的位置(以内存为例)。
所以,在I/O流中的【输入】和【输出】操作分别对应的意思是: 【向内存中输入数据】和【内存向外输出数据】。
②【往电脑的文件中写入数据】情况分析:
当我们向电脑中的某个文件写入数据时,此时电脑的文件是存储在硬盘中的,而我们的java程序是在内存中的。
所以,此时对于内存而言:是将内存中的数据向外输出,输出到硬盘中,所以应该使用 Output【输出流】。
③【读取电脑文件中的数据】情况分析:
当我们读取电脑中某个文件的数据时,此时电脑文件数据在硬盘中,java程序在内存中。
所以,此时对于内存而言,是将别处硬盘中的数据,读取输入到内存中,所以应该使用 Input【输入流】。
④总结:
【向文件中写入数据】----》【数据从内存 流向 文件】----》【对于内存而言:输出数据】----》【用Output输出流】。
【从文件中读取数据】----》【数据从文件 流向 内存】----》【对于内存而言:输入数据】----》【用Input输出流】
2、File文件类
1.简介:
File类是Java.io包下的一个具体类,该类new出的对象代指文件(或者文件夹目录),它可以实现对计算机中的文件、文件夹及其路径进行操作。 比如:创建文件(或文件夹)、获取绝对路径、判断文件是否存在、重命名文件、删除文件、获取当前文件子目录文件或文件夹等一系列操作。
注:File类是对文件整体进行操作,不能修改文件中的内容数据,要修改文件内的数据需要使用【I/O流】进行写入、读取操作。
2.File类的常用方法:
1.创建File对象常用方式:(例:创建一个对象来指代 D:\JIE\jie.txt 文件)
//方式1
File f1 = new File(“D:\JIE\jie.txt”);

//方式2
File f2 = new File(“D:\JIE” , “jie.txt”);//参数1:文件路径,参数2:文件自身名称

//方式3(和方式2类似)
File f = new File(“D:\JIE”);
File f = new File(f , “jie.txt”);
注:①File f = new File(“D:\JIE\jie.txt”); 语句执行时,并没有创建出该文件,只是创建了一个对象来指代这个可能存在的文件。
若要创建出字符串对应名称的文件,还应调用File对象相应的方法如createNewFile();、mkdir();等。
②在File对象构造器中传入路径字符串需要输入: \ 符号时,直接输入会出错,可用如下三种方式:
用转义字符的形式:\ 表示 \ 符号。
用File定义的属性—File.separator 表示 \ 符号。例: “D:”+File.separator+“JIE”+File.separator+“jie.txt”
用 / 代替 \ ,系统会自动转换。(不建议使用)
2.利用 File对象,在电脑中创建文件 或者 文件夹。
//创建文件方式
File f1 = new File(“D:\JIE\jie.txt”);
f1.createNewFile();

//创建文件夹方式
File f2 = new File(“D:\JIE\JIE2”);
f2.mkdir();

//创建多级文件夹方式
File f3 = new File(“D:\JIE\J1\J2\J3”);
f3.mkdirs();
注:①在 f1创建文件 和 f2创建文件夹 的例子中,若上级路径不存在(如:JIE文件夹不存在),则在运行时会有文件路径不存在异常。
在f3创建多级文件夹例子中则不会有这种情况,若父级的文件路径不存在,运行时会自动创建父级文件夹。
②三个方法的返回值都是boolean,若File对象代指的文件不存在,则会创建成功返回true,若已经存在,则会返回false。
③当创建文件对象时,传入的字符串不是绝对路径(从盘符开始的路径),文件则会创建在java程序所在的项目文件的根目录中。
④同一项目文件下,创建文件时,文件的名字 和 文件夹的名字不能重名。
3.删除文件、文件夹
File f = new File(“D:\JIE\jie.txt”);
f.delete(); //删除 f对象指代的文件(或者文件夹)。
注:当delete删除文件时,可直接删除。
但是,当删除文件夹时,若该文件中还有子文件的存在,则无法删除。
4.重命名文件、文件夹(例:将D盘下JIE文件中的 jie.txt文件【重命名】成 newName.txt)
File f = new File(“D:\JIE\jie.txt”);
File newF = new File(“D:\JIE\newName.txt”);
f.renameTo(newF); //重命名,传入一个文件对象。

5.用file对象【剪切】文件,再【粘贴】到另一个位置(例:将D盘下JIE文件中的 jie.txt文件【移动】到D盘的XXX文件夹中)
File f = new File(“D:\JIE\jie.txt”);
File newF = new File(“D:\XXX\jie.txt”);
f.renameTo(newF); /将对象jie.txt文件移动到D盘的XXX文件中(若newF对象创建时改了jie.txt的名字,则移动后名字也改变,文件内容不会改变/

6.对file文件的一些判断
File f = new File(“D:\JIE\jie.txt”);

f.isDirectory(); //判断f对象代指的文件,是否是文件夹。
f.isFile(); //判断f对象代指的文件,是否是普通文件(即不是文件夹的文件)。
f.exists(); //判断f对象代指的文件,是否存在。
f.isFidden(); //判断f对象代指的文件,是否是隐藏文件。
f.canWrite(); //判断f对象代指的文件,是否允许写入数据。
f.canRead(); //判断f对象代指的文件,是否允许读取数据。

7.获取文件的一些属性信息
File f = new File(“D:\JIE\jie”);

f.getAbsolutePath(); //获取f对象指代文件的绝对路径(从电脑盘符开始一级接一级的路径)。
f.getPath(); //获取f对象指代文件的相对路径(从当前java项目文件目录开始查找的文件)。
f.length(); //获取文件的字节数大小(如果f指代的是文件夹,则会返回0,如果指代的是正常文件,则会返回字节大小)。
f.getName(); //获取f对象指代文件的文件名称(出去各级文件夹路径位置的名称)
f.lastModified(); //获取文件最后一次修改的时间,返回的是long类型表示的毫秒值,可根据需要转换成日期数据。

//批量获取文件属性
String[] allName = f.list(); //返回存有f对象所指代文件夹中的所有 子文件和子文件夹 的名称字符串的String数组。
File[] allFile = f.listFile(); //返回文件夹中所有 子文件和子文件夹 组成的File类型数组。

3、java常用的各类I/O流继承关系图
①【字节流】——字节输入流:
在这里插入图片描述

②【字节流】——字节输出流:
在这里插入图片描述

③【字符流】——字符输入流:
在这里插入图片描述

④【字符流】——字符输出流
在这里插入图片描述

4、常用流详解
1.抽象超类【InputStream & OutputStream】 、【Reader & Writer】
①InputStream:所有“字节输入流”的抽象超类。
常用方法:
int read(byte[] be); //从流中,读取数据放入字节数组be,如果be长度为0,则不读取,返回0,如果文件中没有字节可用,则返回-1;
int read(byte[] be,int a,int b); //从流中,读取b个字节的数据,从be数组下标a处开始存入数组。
Abstract int read(); //从流中读取数据的下一个字节。子类会重写(下一个字节内容没数据则返回-1)
void close(); //关闭流

②OutputStream:所有“字节输出流”的抽象超类。
常用方法:
void write(byte[] b); //将字节数组b中的字节内容,写入指定文件
voidwrite(btye b,int a,int b); //将字节数组b中 从a下标开始往后 b长度的的字节数据,写入指定文件
void flush(); //刷新流
void close(); //关闭流
③Reader:所有读取字符流的抽象超类。 Writer:所有写入字符的抽象超类。
常用方法:和前面的类似,可查API。
2.【字节文件输出流 】FileOutputStream & 【字节文件输入流】FileInputStream。
简介:
以字节为单位,传输数据,可用于读取和写入字节文件。如:可用于传输图片、视频、音频等等底层都是字节数据的文件。
对于纯文本文件,可使用字符流(效率快),用字节流也是可以的,因为数据的最底层都是字节数据。
实例:
①【字节文件输出流 】FileOutputStream向文件中写入数据:(向D盘的sun202.txt文件中写入字符 java sun)

public class ADemo {
    public static void main(String[] args) throws IOException {
        String str="D:"+ File.separator+"sun202.txt";
        File f=new File(str);    //创建文件对象
        
        OutputStream o= new FileOutputStream(f,true);   //在[程序]与[文件f]之间创建字节文件输出流。
        
        String s2="java sun";
        byte[] b=s2.getBytes();   //将字符串s2转换成byte数组。
        o.write(b);   //将转换后的byte数组,通过字节文件输出流对象,写入指定文件。
        o.close();
    }
}

②【字节输入流】FileInputStream读取文件中的数据:(读取D盘sun2020.txt文件中的数据)

public class BDemo {
    public static void main(String[] args) throws IOException {
        String str="D:"+ File.separator+"sun202.txt";
        File f=new File(str);  //创建文件对象
        
        InputStream in=new FileInputStream(f);  //在[程序]与[文件f]之间创建字节文件输入流。

        byte[] b=new byte[1024];    //创建一个数组,用于存放读取到的字节数据。
        in.read(b);  //读取文件中的字节数据,并放入数组b中。
        in.close();
       
        String s2=new String(b).trim();//将字节数组转换成字符串并除去首尾的空格。
        System.out.println(s2);
    }
}

注意:
①FileInputStream 使用时所要操作的文件f 必须存在,否则就会有异常。而 FileOutputStream 写入的目标文件则可以不存在,如果文件不存在,系统会帮忙创建出创建该文件。
②new FileOutputStream(f,true)语句中,如果不写true时,新写入的数据会覆盖文件中原有的数据,增加参数true,则是接着在原数据后面追加写入数据。
③只要是流就是需要关闭的,无论是否在异常情况下都需要关闭流,防止占用系统资源,导致其他程序无法对该文件进行操作。在关闭流的时候也有可能会报异常。

3.【字符文件输出流 】FileWriter & 【字符文件输入流 】FileReader#
简介:
FileWriter 和 FileReader 以字符为单位,写入和读取数据。在IDE中使用时,FileWriter 和 FileReader流只能读取IDE默认编码格式的字符流。所以在使用时需要注意操作的文件编码格式,是否与IDE默认的编码格式一致问题。
FileWriter 和 FileReader的底层实现代码其实使用的也是FileInputStream和FileOutputStream。先用字节流读取文件,再用将其转换为我们能看见的字符。
在编码格式统一时,用FileWrite 和 FileReader操作字符文件比较简单。
实例:
①向文件写入数据

public class DDemo {
    public static void main(String[] args) throws IOException {
        String str="D:"+ File.separator+"sun202.txt";
        File f=new File(str);    //创建文件对象
        
        FileWriter w=new FileWriter(f);   //在[程序]与[文件f]之间创建字符文件输出流。
        String s = "jie";
        w.write(s);    //向文件中写入字符串s
        w.close();
    }
}

②读取文件数据

public class CDemo {
    public static void main(String[] args) throws IOException {
        String str="D:"+ File.separator+"sun202.txt";
        File f=new File(str);    //创建文件对象
        
        FileReader r=new FileReader(f);   //在[程序]与[文件f]之间创建字符文件输入流。

        char[] ch=new char[1024];    //创建字符数组
        r.read(ch);    //读取文件f中的数据,并放入ch字符数组中
        r.close();
        System.out.println(Arrays.toString(ch))
    }
}

③编码格式不匹配问题案例:

在这里插入图片描述
*用FileReader流读取GBK编码格式的Test222.txt文件数据。(代码如下)

public class DDemo {
    public static void main(String[] args) throws IOException {
        File f = new File("D:\\Test222.txt");

        FileReader fr = new FileReader(f);
        int len;
        char[] c = new char[20];

        //fr.read(c)方法是读取流中一定的数据放入数组c中。此处使用循环是因为不知道文件中有多少数据
        //然而定义的c数组大小只有20长度,所以使用循环来操作,当数组放满以后,输出来结果,继续用c数组承接新的数据。
        //当文件中的数据都读完以后,c数组没有任何数据可放入时,则会返回-1;所以当len = -1时可退出循环
        while((len=fr.read(c))!=-1){
            System.out.print(String.copyValueOf(c, 0, len));
        }
        fr.close();
    }
}

*运行结果:
在这里插入图片描述

4.【输出转换字符流】OutputStreamWriter & 【输入转换字符流】InputStreamReader。【又称桥接流】
概念:
OutputStreamReader:FileWrite类的父类,可将文件中的数据,以指定的 字节编码格式 读取出来,再转换成字符数据。
InputStreamWriter:FileReader流的父类,可将字符数据,转换成字节数据,再将字节数据以指定的字节编码格式写入文件。
所以这两个流被称作是转换流(或桥接流)。
实例:D盘的【jie1.txt】是GBK编码格式;【jie2.txt】是UTF-8编码格式。(现将 jie.txt 文件中的数据,复制到 jie.txt文件中。)

public class EDemo {
    public static void main(String[] args) throws IOException {
        //先创建文件对象,指代到两个要操作的文件。
        File f1 = new File("D:\\jie1.txt");
        File f2 = new File("D:\\jie2.txt");

        //根据情况分析:从文件f1 读取数据到内存,再将内存中的数据 输出到文件f2,完成复制。
        //文件f1 和 内存之间,建立字节输入流
        //文件f2 和 内存之间,建立字节输出流。
        FileInputStream fi = new FileInputStream(f1);
        FileOutputStream fo = new FileOutputStream(f2);

        //建立对应的转换流
        Reader r = new InputStreamReader(fi, "GBK");//之后的操作会以GBK编码格式读取jie1.txt
        Writer w = new OutputStreamWriter(fo, "UTF-8");//之后的操作会以UTF-8编码格式写入数据到jie2.txt

        char[] c = new char[1024];
        int len = 0;
        while ((len = r.read(c)) != -1) {//用输入转换流r中的编码格式读取字节数据,并转换成字符,保存到c字符数组
            System.out.println(String.copyValueOf(c));//此时读取GBK格式数据在控制台输出也不会乱码。
            w.write(c, 0, len);//将字符数组c中的字符,转换成字节数据,用输出转换流w中的编码格写入到文件中
        }
        r.close();
        w.close();
    }
}

注:
①无论是使用 FileWriter & FileReader 还是 OutputStreamWriter & InputStreamReader,在这些流的内部都会存在缓冲区的,默认大小为8192字节。如果不对流进行关闭的话,数据会继续存在缓冲区,不会存储到文件上。
②手动调用flush()方法,或者在缓冲区中写入的数据超过了缓冲区的大小,数据才会刷新到文件上。
③调用close()方法的时候,内部会先调用flush()刷新缓冲区,将缓冲区的数据都写入进文件。
④上面代码案例中创建的字节流 fi 和 字节流 fo 不需要单独的进行关闭。因为他们作为参数传给了Reader r 和 Writer w后,在这字符流 r 和 w 关闭的时候,会调用字节流的close()方法先将其关闭,所以最后只需要写 r.close(); 和 w.close();。
5、缓冲流:
分类:
【字节输出缓冲流】BufferedOutputStream & 【字节输入缓冲流】BufferedInputStream
【字符输出缓冲流】BufferedWriter & 【字符输入缓冲流】BufferedReader#
概念:
缓冲流,是建立在基础的字节流和字符流基础上的(从命名上也可以大致看出来),基础的字节流和字符流在读取和写入文件时,是一个字节一个字节读取操作的,这样效率很慢。缓冲流会先建立一个缓冲区,先将文件中的数据存在缓冲区,程序要取用数据时,直接在缓冲区中拿,不用再到硬盘文件中一个字节一个字节的取。这样显著提高了文件存取的效率。
(生活举例:有瓜农种了一大片的西瓜,在瓜田旁边搭了个棚子售卖。顾客来买瓜,如果让买瓜的顾客自己去田地里一个一个地摘,效率很慢。所以,一般的情况是,瓜农会准备几个大箩筐,摘满几筐西瓜放在瓜田旁边,买瓜的顾客直接在地旁边的箩筐里拿就行,不用下地去一个一个摘。这里用的箩筐,也就相当于程序中的缓冲区。)
实例 :(将D盘下的xiao.mp3格式的音乐文件,复制一份命名为xiao222.mp3)
(xiao.mp3的大小为4321KB,如果利用普通的字节流来处理,则需要花费很长时间,此处利用缓冲流只需1s左右)

public class KDemo {
    public static void main(String[] args) throws IOException {
        //创建相对于的文件对象
        File f1 = new File("D:\\xiao.mp3");
        File f2 = new File("D:\\xiao222.mp3");

        //创建对应文件的字节流
        FileInputStream fi = new FileInputStream(f1);
        FileOutputStream fo = new FileOutputStream(f2);

        //在字节流的基础上,创建相对于的缓冲字节流
        BufferedInputStream br = new BufferedInputStream(fi,16384);//注:此处的16384是自己定义的缓冲区大小。
        BufferedOutputStream bo = new BufferedOutputStream(fo);//注:如不自定义缓冲区大小,则系统默认定义8192。

        byte[] c = new byte[8192];
        int len = 0;

        //利用缓冲字节流读写
        while ((len = br.read(c)) != -1) {
            bo.write(c,0,len);
        }
        br.close();
        bo.close();
    }
}

6.【字节数组输入流】ByteArrayInputStream & 【字节数组输出流】ByteArrayOutputStream
概念:
操作时,都是以字节数组的形式进行,提升了效率.
实例:

public class ByteArrDemo {
    public static void main(String[] args) throws IOException {
        String fn="d:"+ File.separator+"sun202.txt";
        File f=new File(fn);
        byte[] de=getBy(f);   //调用
        String s2=new String(de);
        System.out.println(s2.trim());
    }
    //字节数组流:读内容  返回类型字节数组
    public static byte[] getBy(File f) throws IOException {
        FileInputStream fi=new FileInputStream(f);
        //引入缓冲流
        BufferedInputStream fin=new BufferedInputStream(fi);

        //先读出内容后,写出到 字节数组中。
        ByteArrayOutputStream bos=new ByteArrayOutputStream();

        byte[] fl=new byte[1024];
        int le=0;
        while( (le=fin.read(fl) )!=-1){
            bos.write(fl,0,le);
        }
       // System.out.println(fl[0]);
        return fl;
    }
}

7.【数据输入流】DataInputStream & 【数据输出流】DataOutputStream。
概念:
当数据类型比较复杂的,有各种数据类型需要输入时,可用数据流(针对java基本类型)。
实例:

public class DataDemo {
    public static void main(String[] args) throws IOException {
        dataFile();
    }
    //通过数据流对文件写 和 读
    public static void dataFile() throws IOException {
        //写入指定数据类型的数据
        FileOutputStream fo=new FileOutputStream("d:\\sun203.txt");
        DataOutputStream dos=new DataOutputStream(fo);

        //针对java基本类型数据
        dos.writeChar(97);
        dos.writeLong(132);
        dos.writeUTF("孙sun");

        //取数据----按序上面的存入的顺序
        FileInputStream fi=new FileInputStream("d:\\sun203.txt");
        DataInputStream dis=new DataInputStream(fi);
       
        System.out.println(dis.readChar());
        System.out.println(dis.readLong());
        System.out.println(dis.readUTF());
    }
}

8.【字节打印流】PrintStream & 【字符打印流】PrintWriter
概念:
java中日常使用的打印语句都是打印在控制台,使用打印流可将打印语句打印到文件中。
实例:

public class PDemo {
    public static void main(String[] args) throws FileNotFoundException {
        //先建立字节输出流
        FileOutputStream fo=new FileOutputStream("D:\\jie.txt",true);
        //建立字节打印流
        PrintStream ps=new PrintStream(fo);  //传入字节流对象fo

        //写入方式1
        ps.write(97);  //会在文件jie.txt中,写入数据97对应的字符a

        //写入方式2
        ps.println(97);  //直接用prinln方法写入数据,参数可以是任意类型的数据值。
        ps.println('x');
        ps.println("hello world");
        ps.println(true);

        //写入方式3
        if(ps!=null){
            System.setOut(ps);  //让系统将ps识别为系统的输出流。
        }
        for(int i=0;i<5;i++){
            System.out.println(i);  //此时系统的输出流已经被换成了ps,会打印到ps指定的文件中。
        }
    }
}

注: PrintWriter 的 close() 方法不会抛出IOException,因为在底层这个异常已经被捕捉并处理了。
5、序列化 及 反序列化(Object对象流)
1.对象流背景:
之前接触的一些流,都是读取或者写入常规的文字、字节等数据。java是一门面向对象语言,最常用的东西就是对象,有时我们可能需要将对象写入到文件中保持,取出时也希望对象数据完整。
于是出现了【对象输出字节流】ObjectOutputStream & 【对象输入字节流】ObjectInputStream。

2.序列化和反序列化概念:
①序列化:将java中的对象整体以流的方式写入到文件中存储,这个过程叫做序列化。(将对象保存硬盘上这个行为叫持久化)
②反序列化:将文件中的对象字节数据,通过流还原成java对象,这个过程叫做反序列化。

3.注意事项:
①一个对象如果想要被序列化,那么要求这个对象对应的类必须实现一个接口—Serailizable接口
该接口中并无需要重写的方法,仅仅用于标志实现这个接口的类的对象允许被序列化。

②无论属性访问权限如何,都可以进行序列化和反序列化。
但是被static、transient修饰的属性不能被序列化。(若想对象的某个属性不被序列化,可在类中该属性前加上transient修饰。)

③序列化的类中需要定义一个属性:serialVersionUID—版本号,(版本号默认用private static final long 修饰限定)。
当一个对象序列化的时候会携带这个类的版本号。
在反序列化的时,系统会检查对象携带的版本号和类中定义的版本号是否一致,如果一致则允许被反序列化。

④若类中没有手动指定版本号,那么Java在编译的时候会根据当前类中的属性和方法自动计算产生一个版本号。这也意味着类中的属性或者方法产生变动,版本号就会改变,已经存好的数据反序列化就会出错。(因此最好手动指定一个序列号,一旦手动指定就不再变化了。)

⑤在Java中数组和集合中的元素,以及大部分的映射不能随着集合或者映射一起序列化。

⑥序列化到文件后是不需要进行flush操作的,同字节流一样也不存在缓冲区。

⑦反序列化后的对象时Object,使用时需要进行相应的强制转换。

4.代码举例

public class FlDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建集合,存入3个对象
        List<Flower> fs = new ArrayList<Flower>();
        Flower f1 = new Flower(1, "玫瑰", 88);
        Flower f2 = new Flower(2, "百合", 99);
        Flower f3 = new Flower(3, "牡丹", 101);
        fs.add(f1);
        fs.add(f2);
        fs.add(f3);
        //调用序列化方法
        ser(fs);
        //调用反序列方法
        fser();
    }
    //将传入的对象集合序列化存入文件中
    public static void ser(List<Flower> list) throws IOException {
        //创建对应【字节文件输出流】
        FileOutputStream fo = new FileOutputStream("d:\\flower.txt");
        //创建【对象输出字节流】
        ObjectOutputStream ob = new ObjectOutputStream(fo);
        //将对象写入文件
        ob.writeObject(list);
        ob.close();
    }
    //反序列化读取文件中的对象内容
    public static void fser() throws IOException, ClassNotFoundException {
        //创建对应的【字节输入流】
        FileInputStream fi = new FileInputStream("d:\\flower.txt");
        //创建对应的【对象输入字节流】
        ObjectInputStream oi = new ObjectInputStream(fi);
        //创建集合,接收反序列化的对象集合
        List<Flower> li = (List<Flower>) (oi.readObject());
        for(Flower l:li){
            System.out.println(l.id+l.name);
        }
    }
}
//花类,实现Serializable接口
class Flower implements Serializable {
    private static final long serialVersionUID = 1008611;//创建版本号
    int id;
    String name;
    int pri;
    
    public Flower(int id, String name, int pri) {
        this.id = id;
        this.name = name;
        this.pri = pri;
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值