chapter14 IO流的相关知识

1-1 IO流的相关介绍

所谓的IO流就是简单的输入和输出,比如把硬盘中的数据,读取到内存中使用。或者把内存中的数据写入到硬盘中
在这里插入图片描述

1-2 IO流的分类

IO流分为字节流和字符流两大类,其中字节流可以处理任何类型的数据,如图片,视频等,字符流只能处理字符类型的数据。因此一旦涉及到文本文件,一般是使用字符流进行处理的。
在这里插入图片描述
注: 由这四个类的子类名称基本都是以其父类名作为子类名的后缀,如果后缀是Reader/Writer是字符流,反之如果是InputStream/OutputStream,那么是字节流,因此可以根据后面的后缀来判断是哪一种类型的流。 如:FileInputStream可以知道这个是字节流, FileReader可以知道其是字符流。

1-2-1字符流

字符流只可以处理文本文件,其他类型数据不行,因此一旦涉及到纯文本文件,一般时用字符流,因为字符流处理文本要比字节流处理文本要方便。字符流分为Reader(输入流)、Writer(输出流)两大类。

1-2-1-1FileWriter

使用字符输出流(FileWriter)的基本步骤:
1、新建一个字符输出流的子类对象FileWriter,并且这个对象的构造参数可以是一个文件名FileName(即字符串)(由于Writer是一个抽象类,所以不可以实例化)

FileWriter几种常见的构造方法:
在这里插入图片描述

2、新建完毕之后,调用write方法,从而向文件名为上面的构造参数的文件进行打印,但是并没有立刻就打印到文件中去,需要进行刷新
3、调用flush()方法,进行刷新,从而将之前write方法中的数据打印到文件中去
4、调用close方法,从而关闭字符输出流,刷新流。调用close方法之后,不可以在调用write方法、flush方法,因为流已经关闭了。
在这里插入图片描述
注意的调用的write()、close()、flush()等方法都已经声明了异常,所以我们的代码中也需要声明异常

字符输出流FileWriter的基本实例:

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

public class FileWriterDemo {
	public static void main(String[] args) throws IOException {
		/**
		 * 新建一个字符输出流,构造参数是一个文件名,表示数据要输入到这个文件中
		 *注意如果这个文件不存在,那么就会自动新建这个文件,如果存在,那么就会将原来的内容进行覆盖
		 *如果不想要将原来的内容进行覆盖,那么在文件名字的后面添加一个boolean类型的参数,如果是true,那么允许续写,
		 *否则就会进行覆盖
		 */
		//步骤一:新建字符输出流对象
		FileWriter fw = new FileWriter("abc.txt");
		
		//步骤二:调用write方法,写入数据,但是并没有立刻写入到文件中去,
		fw.write("hello world");
		fw.write("xixixi");
		fw.write("hahaha");
		fw.write("你好");
		
		//步骤三:调用flush方法进行刷新,从而将之前的数据立刻写入到文件中
		fw.flush();
		
		//步骤四:调用close方法,从而关闭流
		fw.close();
		
	}

}

找到相应的文件abc.txt,打开之后可以看到的结果:
在这里插入图片描述
需要注意的问题:
问题一:在构造参数的时候,如果只是一个文件名,即类似FileWriter fw = new FileWriter(“avc.txt”)这样,那么如果这个文件是不存在的,那么就会自动创建这个文件,否则每一次运行,就会覆盖这个文件的内容。如果不想被覆盖,那么此时需要在文件名的后面添加一个boolean类型的参数,如果是true,表示允许续写,新的数据内容将会写在最后,此时即使这个文件存在,也不会被覆盖,否则如果是false,那么表示不允许续写,就会发生覆盖

问题二:换行的问题
write方法如果是向上面那样的话,那么所有的数据就会拼接在一起,不会换行,此时如果需要换行,那么这时候就要在write()方法里的字符串后面可以添加"\n"即可,即类似write(“hello world\n”)这样即可

问题三:刷新的问题
如果在调用完write方法之后,没有调用flush方法进行刷新会怎样呢?运行一次,找到对应的文件,这里是abc.txt,会发现依旧有和调用flush方法是一样的数据,这是为什么呢?这是因为调用close方法时,在关闭流的最后一步已经调用了flush方法进行刷新了

问题四:调用close方法之后,不可以在调用write方法和flush方法了,否则就会抛出异常,提示流已经关闭了

BufferedFileWriter

这个类继承于Writer的方法,通过这个类,会提高了对数据处理的效率
用法和FileWriter一样,但是他有一个特有方法nextLine(),调用时会发生换行,这个方法只有这个类有。

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

public class BufferedFileWriterDemo {
	
	public static final String LINE_SEPARATOR = System.getProperty("line.separator");//换行,在所有的平台中适用
	public static void main(String[] args) throws IOException {
		/**
		 * 步骤一:新建一个FileWrite对象,构造参数是数据即将输入到的文件,如果这个文件之前已经存在了并且没有boolean类型的参数
		 * 那么就会发生覆盖,如果之前没有这个文件,那么就会自动创建,如果后面有boolean类型参数,那么如果为true,那么允许续写,
		 * 否则不允许续写,从而会发生覆盖
		 */
		FileWriter fw = new FileWriter("abc.txt");
		//步骤二:新建字符输出流对应的缓冲区对象,从而提高对数据的处理效率
		BufferedWriter bw = new BufferedWriter(fw);
		//步骤三:缓冲去对象调用write方法,从而将数据写入到abc.txt目的地
		bw.write("hello java world");
		bw.newLine();//换行
		bw.write("哈哈哈\n");
		bw.write("hello world"+LINE_SEPARATOR);
		bw.write("嘻嘻嘻\n");
		//调用flush方法,从而进行刷新,将数据立即输入到abc.txt这个文件中,但是这一步可以省略,因为调用close方法时同样会进行刷新
		//bw.flush();
		//步骤四:调用close方法,不仅关闭了字符输入流的缓冲区对象,同时关闭了对应的字符输入流
		bw.close();
	}

}

找到相应的文件abc.txt,打开之后可以看到的结果
在这里插入图片描述

1-2-1-2 FileReader

字符读取流(FileReader)基本步骤:
1、新建一个FileReader对象,并且其构造参数是可以是一个字符串,表示要读取文件的名字

FileReader几种常见的构造方法:
在这里插入图片描述

2、调用read()方法,从而读取到文件中的一个字符,并且返回一个整形数字,当然也可以调用read(char[] b)方法,从而返回一个整型数字,表示的是读取到的字符个数,注意的是如果这两个方法返回的是-1,表示已经读取完毕
tips:注意在Reader这个字符输入流中如果调用的read方法中有参数,那么这个参数是char[]字符数组,而不是byte[]字节数组,在InputStream字节输入流中如果调用read方法中有参数的时候,这个参数是一个byte[]字节数组,而不是字符数组char[]
3、调用方法close(),从而关闭字符输入流,关闭流之后,不可以在调用read()等方法。注意FileReader这个流并没有flush方法,要和FileWriter区分开。
实例:

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

public class FileReaderDemo {
	public static void main(String[] args) throws IOException {
		FileReaderDemo frd = new FileReaderDemo();
		frd.read_1();	
	}

	public void read_1() throws IOException {
		//步骤一:新建一个FileReader对象,构造参数是一个要读取的文件的名字
		FileReader fr = new FileReader("abc.txt");
		
		//步骤二:调用方法read(),将会一个一个字符的进行读取,从而读取文件中的内容,
		int c;
		while((c = fr.read()) != -1) {
			System.out.print((char)c);//将整形数字转换成为字符之后输出
		}
		//步骤三:调用方法close(),从而关闭字符输入流
		fr.close();
				
	}

}

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

BufferedReader

字符输入流的缓冲区,这个类继承了Reader类,通过使用这个类,提高了对数据的处理效率。不过他有一个特有方法readLine(),读取文件中的一个数据,返回的是一个String类型,如果返回的是null,表明已经读取完毕
实例:

package day01.io.demo;

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

public class FileReaderDemo {
	public static void main(String[] args) throws IOException {
		FileReaderDemo frd = new FileReaderDemo();
		frd.read_2();
		
	}

	public void read_2() throws IOException {
		//步骤一:新建一个字符输入流对象,构造参数是要进行读取的文件,这个文件必须要存在,否则会抛出异常
		FileReader fr = new FileReader("abc.txt");
		//步骤二:新建缓冲区对象,构造参数是一个字符流对象,从而将两者联系起来
		BufferedReader br = new BufferedReader(fr);
		/**
		 * 步骤三:调用read()方法,从而读取到一个字符,如果调用的是一个read(char[] b)方法,注意参数是char[]字符数组,而不是
		 * 字节数组byte[],这个方法返回的是存放到数组中的字符个数这个两个方法如果返回的是-1,表示已经读取完了
		 * 如果调用的是readLine()方法,那么将会读取文件中的每一行字符,如果返回的是null,表示已经读取完毕
		 */
		
		/**
		 //如果这里通过循环进行读取,那么已经读取完了,下面再调用read(byte[] b)方法直接返回的是-1,不会再进行读取了
		    int c = 0;
			while((c = br.read()) != -1) {
				System.out.print((char)c);
			}
		*/
		
		/**
		  //注意如果调用的read方法中有一个参数,那么这个参数是一个字符数组char[],注意不是byte[]字节数组
		  int c = 0; 
		  char[] b =new char[1024];
		  while((c = br.read(b)) != -1) {
		       System.out.println(new String(b,0,c));
		  }
		 */
		String line = null;
		while((line = br.readLine()) != null) {
			System.out.println(line);
		}
		br.close();//不仅关闭了字符输入流缓冲对象,同时关闭了对应的字符输入流
	}
}

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

1-2-2 字节流

字节流适合所有类型文件的数据传输,因为计算机字节(Byte)是电脑中表示信息含义的最小单位,字节流分为InputStream(输入流)、OutputStream(输出流)两大类。

1-2-2-1 字节输入流

FileInputStream的构造方法:
在这里插入图片描述

FileInputStream(字节输入流)基本步骤和字符输入流的步骤是一样的,这里就直接进入实例了。
实例:

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

public class InputStreamDemo {
	public static void main(String[] args) throws IOException {
		InputStreamDemo in = new InputStreamDemo();
		in.read_1();
	}

	public void read_1() throws IOException {
		//步骤一:新建一个字节输入流,构造参数要进行读取的文件名字
		FileInputStream fis = new FileInputStream("abc.txt");
		
		//步骤二:调用read方法,从而读取一个字符,并且返回一个整数,调用read(byte[] b),
		//从而返回的是一个整数,表示输入到这个数组中的字符个数
		int c = 0;
		byte[] b = new byte[1024];
		while((c = fis.read(b)) != -1) {
			System.out.println(new String(b,0,c));
		}
		
		//步骤三:调用close方法,从而关闭这个字节输入流
		fis.close();
		
	}

}

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

BufferedInputStream

字节输入流的缓冲区对象,基本步骤和BufferedReader一样,但是BufferedInputStream没有readLine方法,而BufferedReader后者有
基本实例:

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class InputStreamDemo {
	public static void main(String[] args) throws IOException {
		InputStreamDemo in = new InputStreamDemo();
		in.read_2();
	}

	public void read_2() throws IOException {
		  //步骤一:新建一个字节输入流,构造参数要进行读取的文件名字
			FileInputStream fis = new FileInputStream("abc.txt");
			//步骤二:新建一个字节输入流的缓冲区对象,构造参数是一个字节输入流,从而将二者联系起来
			BufferedInputStream bis = new BufferedInputStream(fis);
			
			//步骤三:缓冲区对象调用read方法,从而读取一个字符,并且返回一个整数,调用read(byte[] b),
			//从而返回的是一个整数,表示输入到这个数组中的字符个数
			int c = 0;
			byte[] b = new byte[1024];
			while((c = bis.read(b)) != -1) {
				System.out.println(new String(b,0,c));
			}
			
			//步骤三:缓冲区对象调用close方法,不仅关闭这个字节输入流缓冲区对象,同时关闭了字节输入流,此后在调用read方法会抛出异常
			bis.close();
	}

}

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

1-2-2-2 FileOutputStream

FileOutputStream类的构造方法:
在这里插入图片描述

字节输出流(FileOutputStream)基本步骤和FileWriter一样,但是write方法有所不同
在这里插入图片描述
基本实例:

package bytestream;

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

/**
 * 学习字节输出流:
 * 基本步骤和字符流的相似,但是有几点不同:
 * 1、write方法不同,在字符流中,它的参数可以是字符串类型char[],但是在字节流中,不可以是字节流,
 * 而应该是字节数组byte[],因此如果要将字符串作为参数的话,那么这个字符串要转换成为字节数组即调用
 * getBytes方法
 * 2、在字节流中可以不调用flush方法,因为flush方法体没有任何的代码,表明这个方法是没有意义的,同时
 * 调用write方法之后,直接将数据写到了对应的文件中,但是字符流中则需要进行刷新
 */
public class FileOutputStreamDemo {
    public static void main(String[] args)throws IOException {
        //如果这个文件不存在,那么会自动创建,如果存在并且没有boolean类型的数字,那么就会发生覆盖,
        // 如果有,并且是true表示可以续写,将新数据写在最后,否则如果为false,表示不允许续写,此时会发生覆盖
        FileOutputStream fos = new FileOutputStream("bcd.txt",true);//允许续写
        //调用write方法的时候,参数不可以是字符串类型,因此调用方法getBytes,将器转换成为byte[],
        //调用这个方法之后,调用和不调用flush方法是一样的,因为这里的flush方法的方法体是空的,表明了flush方法是没有任何意义的
        fos.write("abcdsiels".getBytes());
        //fos.flush();
        //关闭字节输出流
        fos.close();
    }
}

找到相应的文件abc.txt,可以知道结果为:
在这里插入图片描述

BufferedOutputStream

基本步骤和BufferedOutputStream一样,那么基本实例:

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //步骤一:新建字节流输出对象,构造参数是要写入的文件名,
        FileOutputStream fos = new FileOutputStream("bcd.txt");
        //步骤二:新建字节输出流的缓冲区对象,并且构造参数为字节输出流,从而将两者联系起来
        BufferedOutputStream bos = new BufferedOutputStream(fos);//新建字节输出流的缓冲对象
        //步骤三:缓冲区对象调用write方法,从而将数据写入到对应的文件中
        bos.write("hello java language\n".getBytes());
        bos.write("hello world\n".getBytes());
        //步骤四:缓冲区队形调用close方法,从而不仅关闭了缓冲对象,同时关闭了输入流对象
        bos.close();

    }
}

找到相应的文件bcd.txt,打开之后结果为:
在这里插入图片描述

2 File类

File类的几种构造方法
在这里插入图片描述
几个常用的方法:

1、public String getName()
返回由此抽象路径名表示的文件或目录的名称。
2、public String getPath()获取文件的相对路径
3、public String getAbsolutePath()获取文件的绝对路径
4、public boolean exists()判断文件或目录是否存在。
5、public boolean isDirectory()判断是否是一个目录。
6、public boolean isFile()判断是否是一个文件
7、public long lastModified()返回文件最后一次被修改的时间
8、public long length()文件的长度(即大小)
9、public boolean createNewFile() throws IOException
当且仅当不存在具有此抽象路径名指定的名称的文件时,原子地创建由此抽象路径名指定的一个新的空文件。
10、public boolean delete()shiyi 删除此抽象路径名表示的文件或目录。
11、public void deleteOnExit()在虚拟机终止时(即在程序结束的最后一步)删除此抽象路径名表示的文件或目录。
12、public String[] list()返回由此抽象路径名所表示的目录中的文件和目录的名称,注意是文件或者文件夹的名字所组成字符串数组
13、public String[] list(FilenameFilter filter)返回由此抽象路径名所表示的目录中的文件和目录的名称,注意是文件或者文件夹的名字所组成字符串数组,这一目录是通过满足指定过滤器的抽象路径名来表示的
14、public File[] listFiles()
返回一个抽象路径名数组,注意这个数组的元素是一个File类对象,这些路径名表示此抽象路径名所表示目录中的文件

15 public File[] listFiles(FileFilter filter)
返回表示此抽象路径名所表示目录中的文件和目录的抽象路径名数组,这些路径名满足特定过滤器

16 public boolean mkdir()创建此抽象路径名指定的目录。
17 public boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。

3 各种流

3-1 转换流

InputStreamReader 用于将字节输入流转换为字符输入流
OutputStreamWriter 用于将字节输出流转换为字符输出流
使用转换流可以在一定程度上避免乱码,还可以指定输入输出所使用的字符集。有时候为了提高效率,用到了字符流的缓冲区对象

没有使用转换流时,读取键盘输入的数据,并将其打印在控制台上:

import java.io.*;

public class TransStreamTest_0 {
    public static void main(String[] args) throws IOException {
        //调用方法,读取键盘录入的数据
        practice_1();
    }

    private static void practice_1() throws IOException {
        //新建一个字节输入流对象
        InputStream in = System.in;//调用System类的静态方法in,从而返回一个InputStream对象,从而知道读取的对象是键盘输入的数据
        /*
        //直接调用read方法进行读取,效率低
        int c = 0;
        StringBuilder sb = new StringBuilder();
        while((c=in.read()) != -1){
            if(c == '\r')
                continue;
            if(c == '\n'){
                String str = sb.toString();
                if(str.equals("over"))
                    break;
                System.out.println(str.toUpperCase());
                sb.delete(0,str.length());//重置StringBuilder对象
            }
            else
                sb.append((char)c);
        }
        */
        //新建缓冲区对象,然后再调用read方法,从而提高对数据处理的效率
        BufferedInputStream bis = new BufferedInputStream(in);
        StringBuilder sb = new StringBuilder();
        int c = 0;
        while((c = bis.read()) != -1){
            if(c == '\r')
                continue;
            if(c == '\n'){
                String str = sb.toString();
                if(str.equals("over"))
                    break;
                System.out.println(str);
                sb.delete(0,str.length());//重置StringBuilder对象
            }
            else
                sb.append((char)c);
        }
        bis.close();//关闭字节输入流的缓冲区对象,同时关闭对应的字节输入流
    }
}

结果:
在这里插入图片描述
根据运行结果,没有使用转换流时,可以发现输入中文的时候出现了乱码。

使用转换流之后,实例代码:

package transstreamtest;

import java.io.*;

public class TransStreamTest_1 {
    public static void main(String[] args) throws IOException {
        test_2();//调用方法,将字节流转换成为字符流
    }

    //字节流转换成为字符流---InputStreamReader   这里有必要和读取键盘录入的内容区分开,如果读取键盘录入的内容,
    // 则如果是中文,会发生乱码,但是如果将字节流转换成为字符流,则不会发生乱码
    private static void test_2() throws IOException {
       /*
       //1、新建一个字节流对象,从而知道读取对象
        InputStream in = System.in;
        //步骤二:调用InputStreamReader,从而将字节流转换成为字符流
        InputStreamReader isr = new InputStreamReader(in);

        //步骤三:为了提高对数据处理的效率,因此新建对应的字符流的缓冲区对象
        BufferedReader br = new BufferedReader(isr);
        */
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//一行代码解决字节流转换成为字符流,同时新建对应的缓冲对象
        String str = null;
        while((str = br.readLine()) != null){
            if(str.equals("over"))
                break;
            System.out.println(str);
        }
        //步骤四:关闭缓冲对象及对应的字符流对象
        br.close();
    }
}

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

3-2 序列流

序列流(SequenceInputStream:):作用就是将多个读取流合并成一个读取流,实现数据的合并
序列流不仅可以合并文本文件,也可以合并其它类型的文件, 因为后缀是InputStream,表示它是一个字节流,字节流可以处理任何类型的文件。

构造方法:
在这里插入图片描述
合并多个文本文件基本实例:

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;

public class SequenceInputStreamDemo {

    public static void main(String[] args) throws IOException {
     /*
     //通过调用Vector对象的elements的方法,从而返回一个枚举类型
        Vector<FileInputStream> fis = new Vector<>();
        fis.addElement(new FileInputStream("新复制.txt"));
        fis.addElement(new FileInputStream("缓冲区.txt"));
        Enumeration<? extends InputStream> en = fis.elements();//返回枚举类型
        */
        ArrayList<FileInputStream> list = new ArrayList<>();//创建一个集合
        list.add(new FileInputStream("E:\\IDEAworkspace\\day01.io.demo\\PracticeTxt\\新复制.txt"));
        list.add(new FileInputStream("E:\\IDEAworkspace\\day01.io.demo\\PracticeTxt\\缓冲区.txt"));
        //将调用Collections这个工具类中的enumeration方法,从而返回一个枚举类型
        /*
        这个方法的源代码的原理是这个样的:
        Iterator<FileInputStream> it = list.iterator();//构建迭代器
        Enumeration<FileInputStream> en = new Enumeration(){//构建一个枚举类型
             public boolean hasElements(){
                  return it.hasNext();//调用list的迭代器,从而将判断这个迭代器中是否还有元素
             }
             public FileInputStream nextElement(){
                  return it.next();//调用list的迭代器,从而返回对应的元素
             }
        };
         */
        Enumeration<?extends InputStream> en = Collections.enumeration(list);//将调用Collections这个工具类中的enumeration方法,从而返回一个枚举类型
        //创建序列流,如果有两个读取流时,那么构造参数可以是两个读取流,当然也可以是枚举类型,
        // 但是如果有超过两个流,那么构造参数必然是一个枚举类型的读取流
        SequenceInputStream s = new SequenceInputStream(en);
        //将序列流中的内容打印到序列流.txt这个文件中
        BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("E:\\IDEAworkspace\\day01.io.demo\\PracticeTxt\\序列流.txt"));
        byte[] b = new byte[1024];
        int c;
        //读取序列流,从而将序列流中的内容添加到对应的文件中
        while((c = s.read(b)) != -1){
            String string = new String(b, 0,c);
            bw.write(string.getBytes());
        }
        s.close();//关闭序列流
        bw.close();//关闭缓冲对象,同时关闭对应的读取流
    }
}


找到相应的文件序列流.txt,打开之后结果为:
在这里插入图片描述

3-3 对象流

对象序列化:
对象输出流(ObjectOutputStream):是OutputStream的子类,因此除了write等方法之外,它还有一个特有方法writeObject(Obejcet obj),从而将对象写入到相应的文件中去,注意的是这个obj对象必须要实现Serializable接口,否则就没有办法实现对象的序列化,同时输入完毕之后,打开相应的文件,会发现出现了乱码,这是因为使用的是默认的编码表

对象序列化的实例:

Person类:

import java.io.Serializable;

public class Person implements Serializable {
//要实现对象的序列化,那么这个对象必须要实现Serializable接口
    private String name;
    private int age;
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "{ 姓名:"+name +", 年龄: "+ age +"}";
    }
}

测试类:

import java.io.*;

public class ObjectInputStreamDemo {
    public static final String LINE_SEPARATOR = System.getProperty("line.separator");//换行
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStreamDemo oisd = new ObjectInputStreamDemo();
        oisd.writeDemo();//调用方法,从而将对象序列化
        oisd.readDemo();//调用方法,将对象反序列化
    }

    public void readDemo() throws IOException, ClassNotFoundException {
        File file = new File("E:\\IDEAworkspace\\day01.io.demo\\PracticeTxt\\对象序列化.txt");
        FileInputStream fos = new FileInputStream(file);

        ObjectInputStream ops = new ObjectInputStream(fos);//将对应的文件进行读取
        Object obj = null;
        while((obj = ops.readObject()) != null){
            System.out.print(obj.toString()+LINE_SEPARATOR);
        }
        fos.close();//关闭字节输入流
        ops.close();//关闭对象输入流
    }

    public void writeDemo() throws IOException {
        File file = new File("E:\\IDEAworkspace\\day01.io.demo\\PracticeTxt\\对象序列化.txt");
        //将对象写入到文件对象序列化.txt中
        FileOutputStream fos = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //添加的对象必须是实现了Serializable接口,从而实现序列化,否则就会抛出NotSerializableException异常
        //此时去看对应的文件的时候,就会发现有发生了乱码,只是正常的,这是因为使用的是默认的编码表
        oos.writeObject(new Person("小王",23));
        oos.writeObject(new Person("向天",26));
        oos.writeObject(new Person("小陈",25));
        oos.writeObject(new Person("小李",18));
        oos.writeObject(null);//最后要添加一个null,因为在通过循环调用readObject时防止抛出EODException,如果没有这一步,就会抛出异常
        fos.close();//关闭字节输出流
        oos.close();//关闭对象输出流
    }
}

结果:
在这里插入图片描述
写的不好地方,请大家指正哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值