java基础-IO流

IO流

IO简介

对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能。程序运行需要数据,数据的获取往往需要跟外部系统进行通信,外部系统可能是文件、数据库、其他程序、网络、IO设备等。外部系统比较复杂多变,那么我们有必要通过某种手段进行抽象、屏蔽外部差异,从而实现更加便捷的编程。

1.输入(Input)指的是:可以让程序从外部系统获得数据(核心含义是“读”,读取外部数据)

  • 读取硬盘上的文件内容到程序。例如:播放器打开一个视频文件、word打开一个doc文件。
  • 读取网络上某个位置内容到程序。例如:浏览器中输入网址后,打开该网址对应的网页内容;下载网络上某个网址的文件。
  • 读取数据库系统的数据到程序。
  • 读取某些硬件系统数据到程序。例如:车载电脑读取雷达扫描信息到程序;温控系统等
    2.输出(Output)指的是:程序输出数据给外部系统从而可以操作外部系统(核心含义是“写”,将数据写出到外部系统)
  • 将数据写到硬盘中
  • 将数据写到数据库系统中
  • 将数据写到某些硬件系统中

数据源

数据源 Data Source,提供数据的原始媒介。常见的数据源有:数据库、文件、其他程序、内存、网络连接、IO设备

数据源分为:源设备、目标设备

  • 源设备:为程序提供数据,一般对应输入流
  • 目标设备:程序数据的目的地,一般对应输出流

流的概念

1.流是一个抽象、动态的概念,是一连串连续动态的数据集合
2.对于输入流而言,数据源就像水箱,流(Stream)就像水管中流动着的水流,程序就是我们的最终用户。我们通过流(A Stream)将数据源中的数据输送到程序中
3.对于输出流而言,目标数据源就是目的地,我们通过流将程序中的数据输送到目的数据源中。

输入/输出流的划分是相对程序而言的,并不是相对数据源

IO流程序

public class PathDemo01 {
    public static void main(String[] args) throws IOException {
        try{
            //创建输入流
            FileInputStream fis = new FileInputStream("F:a.txt");//文件内容是:abc
            //一个字节一个字节的读取数据
            int s1 = fis.read();//打印输入字符a对应的ASCII码值97
            int s2 = fis.read();//打印输入字符b对应的ASCII码值98
            int s3 = fis.read();//打印输入字符c对应的ASCII码值99
            int s4 = fis.read();//由于文件内容已经读取完毕,返回-1
            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s3);
            System.out.println(s4);
            //流对象使用完,必须关闭!不然,总占用系统资源,最终会造成系统崩溃
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

1.我们读取的文件内容是已知的,因此可以使用固定次数的“int s= fis.read();”语句读取内容,但是在实际开发中通常我们根本不知道文件的内容,因此我们在读取的时候需要配合while循环使用。
2.为了保证出现异常后流的正常关闭,通常要将流的关闭语句要放到finally语句块中,并且要判断流是不是null

//经典代码
public class TestIO2 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = null;
        try{
            fis = new FileInputStream("F:/idea代码/IO流/a.txt");
            StringBuilder sb = new StringBuilder();
            int temp = 0;
            //当temp等于-1时,表示已经到了文件结尾,停止读取
            while((temp = fis.read()) != -1){
                sb.append((char)temp);
            }
            System.out.println(sb);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally{
            try{
                //这种写法,保证了即使遇到异常情况,也会关闭流对象
                if(fis != null){
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

四大IO抽象类

InputStream

此抽象类是表示字节输入流的所有类的父类。InputStream是一个抽象类,不可实例化。数据的读取需要由它的子类来实现。根据节点的不同,他派生了不同的节点流子类。
继承自 InputStream 的流都是用于向程序中输入数据,且数据的单位为字节(8bit)

常用方法:

int read():读取一个字节的数据,并将字节的值作为int类型返回(0-255)
未读出返回-1
void close();关闭输入流对象,释放相关系统资源

OutputStream

此抽象类是表示字节输出流的所有类的父类。输出流接收输出字节并将这些字节发送到某个目的地

常用方法:

void write(int n):向目的地写入一个字节
void close();关闭输出流对象,释放相关系统资源

Reader

用于读取的字符流抽象类,数据单位为字符
int read():读取一个字符的数据,并将字节的值作为int类型返回(0-65535)
未读出返回-1
void close();关闭输入流对象,释放相关系统资源

Writer

用于输出的字符流抽象类,数据单位为字符
void write(int n):向输出流写入一个字符
void close();关闭输出流对象,释放相关系统资源

  • 节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。
  • 处理流:不直接连接到数据源或目的地,是“处理流的流”。通过对其他流的处理提高程序性能,如:BufferedInputStream、BuffereReader等。处理流也叫包装流

File类

1.File类简介

1.1作用:

File类是Java提供的针对磁盘中的文件或目录转换对象的包装类。一个File对象可以代表一个文件或目录,File对象可以实现获取文件和目录属性等功能,可以实现对文件和目录的创建,删除等功能

1.2File类操作目录与文件的常用方法

1.2.1针对文件的操作方法

createNewFile()//创建新文件
delete()//直接从磁盘上删除
exists()//查询磁盘中的文件是否存在
getAbsolutePath()//获取绝对路径
getPath()//获取相对路径
getName()//获取文件名 相当于调用了一个to String 方法
isFile()//判断是否是文件
length()//查看文件中的字节数
isHidden()//测试文件是否被这个抽象路径名是一个隐藏文件

        //创建一个file对象
        File file = new File("d:/aaa.txt");
        try {
            System.out.println(file.createNewFile());//创建新文本文件
            System.out.println(file.exists());//查询磁盘中的文件是否存在
            System.out.println(file.getAbsolutePath());//获取绝对路径
            System.out.println(file.getPath());//获取相对路径
            System.out.println(file.getName());//获取文件名,相当于调用了一个toString方法
            System.out.println(file.isFile());//判断是否是文件
            System.out.println(file.length());//查看文件中的字节数
            System.out.println(file.isHidden());//测试文件是否这个抽象路径名是一个隐藏文件
            System.out.println(file.delete());//从磁盘删除文件
        }catch(Exception e){
            e.printStackTrace();
        }
       
1.2.2针对目录的操作方法

exists()//查询目录是否存在
isDirectory()//判断当前路径是否为目录
mkdir()//创建目录
getParentFile()//获取当前目录的父级目录
list()//返回一个字符串数组,包含目录中的文件和目录的路径名
listFiles//返回一个File数组,表示用此抽象路径名表示的目录中的文件

        //创建file对象
        File file = new File("d:/AAAA");
        File file1 = new File("d:/aaaa/aaa/aa/a");
        System.out.println(file.mkdir());
        System.out.println(file1.mkdirs());
        System.out.println(file.exists());//查询目录是否存在
        System.out.println(file.isDirectory());//判断当前路径是否为目录
        System.out.println(file.getParentFile());//获取当前目录的父级目录
        System.out.println(file1.getParentFile());
        File file2 = new File("d:/aaaa");
        String[] arr = file2.list();//返回一个字符串数组,包含目录中的文件和目录的路径名
        for (String temp :
                arr) {
            System.out.println(temp);
        }
        File[] arr2 = file2.listFiles();//返回一个File数组,表示用此抽象路径名表示的目录中的文件
        for (File temp :
                arr2) {
            System.out.println(temp);
        }

        System.out.println(file.delete());
        System.out.println(file1.delete());
       

常用类对象

1.文件字节流

1.1文件字节输入流

FileInputStream通过字节的方式读取文件,适合读取所有类型的文件。Java也提供了FileReader专门读取文本文件
FileOutputStream通过字节的方式写数据到文件,适合所有类型的文件。Java也提供了FileWriter专门读取文本文件

1.2文件字节输出流

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //创建一个文件字节流对象
            fis = new FileInputStream("d:/QQ/卢本伟牛逼.png");
            fos = new FileOutputStream("d:/QQ/aaa.png");
            int count = 0;
            int temp = 0;
            while ((temp = fis.read()) != -1){
                count++;
                fos.write(temp);
            }
            //刷新
            fos.flush();
            System.out.println("字节的个数为:" + count);
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流对象
                if(fis != null){
                    fis.close();
                }
                if(fos != null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /*
        运行结果:字节的个数为:491469
        */

1.3通过缓冲区提高读写效率

1.3.1方式一

通过创建一个指定长度的字节数组作为缓冲区,以此来提高IO流的读写效率。该方式用于读取较大图片时的缓冲区定义。

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //创建一个文件字节流对象
            fis = new FileInputStream("d:/QQ/卢本伟牛逼.png");
            fos = new FileOutputStream("d:/QQ/bbb.png");
            //增加缓冲区
            byte[] arr = new byte[1024];
            int temp = 0;
            while ((temp = fis.read(arr)) != -1){
                fos.write(arr,0,temp);
            }
            //刷新
            fos.flush();
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流对象
                if(fis != null){
                    fis.close();
                }
                if(fos != null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

1.3.2方式二

通过创建一个字节数组作为缓冲区,数组长度是通过输入流对象的available()返回当前文件的预估长度来定义的。在读写文件时,是在一次读写操作中完成文件读写操作的

               FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //创建一个文件字节流对象
            fis = new FileInputStream("d:/QQ/卢本伟牛逼.png");
            fos = new FileOutputStream("d:/QQ/bbb.png");
            //创建一个缓冲区
            byte[] arr = new byte[fis.available()];
            fis.read(arr);
            fos.write(arr);
            //刷新
            fos.flush();
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流对象
                if(fis != null){
                    fis.close();
                }
                if(fos != null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }


1.4通过字节缓冲流提高读写效率

java缓冲流本身并不具有IO流的读取与写入功能,只是在别的流(节点流或其他处理流)上加上缓冲功能提高效率,就像是把别的流包装起来一样,因此缓冲流是一种处理流(包装流)。
BufferedInputStream和BufferedOutputStream这两个流是缓冲字节流,通过内部缓存数组来提高操作流的效率。

           FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            fis = new FileInputStream("d:/QQ/卢本伟牛逼.png");
            bis = new BufferedInputStream(fis);
            fos = new FileOutputStream("d:/QQ/ddd.png");
            bos = new BufferedOutputStream(fos);
            int temp = 0;
            //缓冲区byte数组的默认长度是8192
            while((temp = bis.read()) != -1){
                bos.write(temp);
            }
            //刷新
            bos.flush();
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            //关闭的原则:“先开后关”
            try {
                if(bis != null){
                    bis.close();
                }
                if(fis != null){
                    fis.close();
                }
                if(bos != null){
                    bos.close();
                }
                if(fos != null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

1.5定义文件拷贝工具类

    /**
     *
     * @param src 源文件的路径
     * @param des 需要拷贝文件的路径
     */
    public static void copyFile(String src, String des){
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            fis = new FileInputStream(src);
            bis = new BufferedInputStream(fis);
            fos = new FileOutputStream(des);
            bos = new BufferedOutputStream(fos);
            int temp = 0;
            while ((temp = bis.read()) != -1){
                bos.write(temp);
            }
            bos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if(bis != null){
                    bis.close();
                }
                if(fis != null){
                    fis.close();
                }
                if(bos != null){
                    bos.close();
                }
                if(fos != null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

2.文件字符流

以字符为单位进行操作

2.1文件字符输入流

        FileReader frd = null;
        try {
            frd = new FileReader("d:/QQ/AAA/aaa.txt");
            int temp = 0;
            while((temp = frd.read()) != -1){
                System.out.println((char)temp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if(frd!=null){
                    frd.close();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
       

2.2文件字符输出流

        FileWriter fw = null;
        FileWriter fw2 = null;
        try {
            fw = new FileWriter("d:/QQ/AAA/abc.txt");
            fw.write("你好尚学堂\r\n");
            fw.write("来到世界最高层理塘\r\n");
            fw.flush();

            fw2 = new FileWriter("d:/QQ/AAA/abc.txt",true);
            fw2.write("呀,这不是丁真吗?\r\n");
            fw2.write("看看远处的雪山吧,家人们\r\n");
            fw2.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if(fw!=null){
                    fw.close();
                }
                if(fw2!=null){
                    fw2.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

2.3使用字符流实现文本文件的拷贝处理

        FileReader fr = null;
        FileWriter fw = null;
        try {
            fr = new FileReader("d:/QQ/AAA/abc.txt");
            fw = new FileWriter("d:/QQ/AAA/abc123.txt");
            //创建缓冲区char类型数组,数组长度为1024
            char[] arr = new char[1024];
            int temp = 0;
            while ((temp = fr.read(arr)) != -1){
                fw.write(arr,0,temp);
            }
            fw.flush();
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流对象
                if(fr != null){
                    fr.close();
                }
                if(fw != null){
                    fw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

3.字符缓冲流

BuffereReader/BuffereWriter增加了缓存机制,大大提高了读写文本文件的效率

3.1字符输入缓冲流

BuffereReader是针对字符输入流的缓冲流对象,提供了更方便的按行读取的方法:readLine();在使用字符流读取文本文件时,可以使用该方法以行为单位进行读取。

        FileReader fr = null;
        BufferedReader br = null;
        try {
            fr = new FileReader("d:/QQ/AAA/abc.txt");
            br = new BufferedReader(fr);
            String temp = null;
            while((temp = br.readLine()) != null){
                System.out.println(temp);
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流对象
                if(br != null){
                    br.close();
                }
                if(fr != null){
                    fr.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /*
        运行结果:你好尚学堂
				来到世界最高层理塘
				呀,这不是丁真吗?
				看看远处的雪山吧,家人们
        */

3.2字符输出缓冲流

BuffereWriter是针对字符输出流的缓冲流对象,在字符输出缓冲流中可以使用newLine();方法实现换行处理

        FileWriter fw = null;
        BufferedWriter bw = null;
        try {
            fw = new FileWriter("d:/QQ/AAA/sxt.txt");
            bw = new BufferedWriter(fw);
            bw.write("来到世界最高层理塘");
            bw.write("呀,这不是丁真吗");
            bw.newLine();
            bw.write("嘭");
            bw.newLine();
            bw.write("看看远处的雪山吧家人们");
            bw.flush();
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流对象
                if(bw != null){
                    bw.close();
                }
                if(fw != null){
                    fw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /*
        文件的内容为:来到世界最高层理塘呀,这不是丁真吗
					嘭
					看看远处的雪山吧家人们
        */

3.3通过字符缓冲流实现文本文件的拷贝

    /**
     * 基于字符缓冲流实现文件拷贝
     * @param src 读取文件的路径
     * @param des 写出文件的路径
     */
    public static void copyFile(String src,String des){
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader(src));
            bw = new BufferedWriter(new FileWriter(des));
            String temp = "";
            while ((temp = br.readLine()) != null){
                bw.write(temp);
                bw.newLine();
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流对象
                if(br != null){
                    br.close();
                }
                if(bw != null){
                    bw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

3.4通过字符缓冲流为文件中的内容添加行号

        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader("d:/QQ/AAA/abc123.txt"));
            bw = new BufferedWriter(new FileWriter("d:/QQ/AAA/123abc.txt"));
            String temp = "";
            int i = 1;
            while ((temp = br.readLine()) != null){
                bw.write(i+"、"+temp);
                bw.newLine();
                i++;
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭流对象
                if(br != null){
                    br.close();
                }
                if(bw != null){
                    bw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /*
        输出文件的内容为:1、你好尚学堂
						2、来到世界最高层理塘
						3、呀,这不是丁真吗?
						4、看看远处的雪山吧,家人们
        */

4. 转换流

InputStreamReader/OutputStreamWriter用来实现将字节流转换成字符流

4.1通过转换流实现键盘输入屏幕输出

        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            bw = new BufferedWriter(new OutputStreamWriter(System.out));
            bw.write("请输入:");
            bw.flush();
            String input = br.readLine();
            bw.write(input);
            bw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if(br!=null){
                    br.close();
                }
                if(bw!=null){
                    bw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /*
        运行结果:请输入:我是中国人
				我是中国人
        */

4.2通过字节流读取文本文件并添加行号

        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream("d:/QQ/AAA/abc.txt")));
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:/QQ/AAA/123.txt")));
            int i = 1;
            String temp = "";
            while((temp = br.readLine()) != null){
                bw.write(i+"、"+temp);
                bw.newLine();
                i++;
            }
            bw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if(br!=null){
                    br.close();
                }
                if(bw!=null){
                    bw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /*
        输出文件的内容为:1、你好尚学堂
						2、来到世界最高层理塘
						3、呀,这不是丁真吗?
						4、看看远处的雪山吧,家人们
        */

5.字符输出流

PrintWriter:用于字符输出的流对象。该对象有自动行刷新缓冲字符输出流,即不需要调用flush()方法。特点是可以按行写出字符串,并且可通过println()方法实现自动换行。

        BufferedReader br = null;
        PrintWriter pw = null;
        try {
            br = new BufferedReader(new FileReader("d:/QQ/AAA/abc.txt"));
            pw = new PrintWriter("d:/QQ/AAA/td.txt");
            int i = 1;
            String temp = "";
            while((temp = br.readLine()) !=null){
                pw.println(i+"、"+temp);
                i++;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if(br!=null){
                    br.close();
                }
                if(pw!=null){
                    pw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

6.字节数组流

ByteArrayInputStream和ByteArrayOutputStream用于流和数组之间转化

6.1字节数组输入流

1.FileInputStream是把文件当作数据源,ByteArrayInputStream则是把内存中的“字节数组对象”当作数据源
2.该对象构造方法的参数是一个字节数组,这个字节数组就是数据源
bais = new ByteArrayInputStream(arr);

        byte[] arr = "agacgg".getBytes();
        ByteArrayInputStream bais = null;
        StringBuffer buffer = new StringBuffer();
        try {
            //该构造方法的参数是一个字节数组,这个字节数组就是数据源
            bais = new ByteArrayInputStream(arr);
            int temp = 0;
            while((temp = bais.read()) != -1){
                buffer.append((char)temp);
            }
            System.out.println(buffer.toString());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(bais!=null){
                    bais.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /*
        运行结果:agacgg
        */

6.2字节数组输出流

1.ByteArrayOutputStream流对象是将流中的数据写入到字节数组中
2.byte toByteArray( )[ ]:将流对象转换为字节数组,返回一个字节数组

        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();
            baos.write('a');
            baos.write('b');
            baos.write('c');
            baos.write('d');
            baos.write('e');
            byte[] bytes = baos.toByteArray();
            for (int i = 0; i < bytes.length; i++) {
                System.out.println((char)bytes[i]);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(baos!=null){
                    baos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /*
        运行结果:a
				b
				c
				d
			 	e
        */

7.数据流

数据流将“基本数据类型与字符串类型”作为数据源,从而让输入输出流操作Java基本数据类型与字符串类型
DataInputStream和DataOutputStream提供了所有基本类型数据(如int,doulbe,String等)方法

        DataOutputStream dos = null;
        DataInputStream dis = null;
        try {
            dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("D:/QQ/AAA/DataStream.txt")));
            dos.writeBoolean(true);
            dos.writeChar('g');
            dos.writeDouble(10.12);
            dos.writeInt(50);
            dos.flush();
            dis = new DataInputStream(new BufferedInputStream(new FileInputStream("D:/QQ/AAA/DataStream.txt")));
            //直接读取数据,注意:读取的顺序要与写入的顺序一致,否则不能正确读取
            System.out.println(dis.readBoolean());
            System.out.println(dis.readChar());
            System.out.println(dis.readDouble());
            System.out.println(dis.readInt());

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(dos!=null){
                    dos.close();
                }
                if(dis!=null){
                    dis.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        /*
        运行结果:true
				g
				10.12
				50
        */

8.对象流

8.1Java对象的序列化和反序列化

8.1.1序列化和反序列化

当两个进程远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。
1.对象的序列化:把Java对象转换为字节序列的过程
2.对象的反序列化:把字节序列恢复为Java对象的过程
3.对象序列化的作用:a.持久化:把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中
b.网络通信:在网络上传送对象的字节序列。

8.1.2序列化涉及的类和接口

1.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
2.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把他们反序列化为一个对象,并将其返回。
3.Serializable接口是一个空接口,只起标记作用。只有实现了Serializable接口的类的对象才能被序列化。

8.2写出和读取操作基本数据类型

8.3将对象序列化到文件和反序列化到内存中

ObjectOutputStream可以将一个内存中的Java对象通过序列化的方式写入到磁盘的文件中。被序列化的对象必须要实现Serializable序列化接口,否则会抛出异常

        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("d:/QQ/AAA/ObjectStreamObject.txt"));
            Users users1 = new Users(10, "张三", 23);
            oos.writeObject(users1);

            ois = new ObjectInputStream(new FileInputStream("d:/QQ/AAA/ObjectStreamObject.txt"));
            Users users2 = (Users)ois.readObject();
            System.out.println(users2.getId());
            System.out.println(users2.getName());
            System.out.println(users2.getAge());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(oos!=null){
                    oos.close();
                }
                if(ois!=null){
                    ois.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
       

9.随机访问流

RandomAccessFile可以实现两个作用:①实现对一个文件做读和写的操作。②可以访问文件的任意位置。
三个核心方法:
1.构造方法RandomAccessFile(String name, String mode):name用来确定文件;mode取r(读)或者rw(读写),通过mode可以确定流对文件的访问权限
2.seek(long a):用来定位流对象读写文件的位置,a确定读写位置距离文件开头的字节个数
3.getFilePointer() :获取流的当前读写位置。

        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile("d:/QQ/AAA/RandomAccessFile.txt","rw");
            //将数据写入文件中
            int[] arr = new int[]{10,20,30,40,50,60,70,80,90,100};
            for (int i = 0; i < arr.length; i++) {
                raf.writeInt(arr[i]);
            }
            //将数据隔三个读出
            for (int i = 0; i < arr.length; i+=3) {
                raf.seek(i*4);
                System.out.print(raf.readInt() + "\t");;
            }
            System.out.println();
            //将第四个数据替换成110
            raf.seek(4*3);
            raf.writeInt(110);
            //将数据隔三个读出
            for (int i = 0; i < arr.length; i+=3) {
                raf.seek(i*4);
                System.out.print(raf.readInt() + "\t");;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(raf!=null){
                    raf.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        

10. File类在IO流中的作用

当以文件作为数据源或自标时,除了可以使用字符串作为文件以及位置的指定以外,我们也可以使用File类指定

Apache IO包

1.FileUtils的使用

常用方法

1.读入文件内容
readFileToString(文件需要写入的内容,字符集)

String content = FileUtils.readFileToString(new File("d:/QQ/AAA/abc/txt"),"UTF-8");
System.out.println(content);

2.将已筛选的目录拷贝到新位置:
copyDirectory(File srcDir, File destDir, FileFilter filter)

String destFilePath = "E:\java\file04";
//将已筛选的目录复制,并保持原文件日期的新位置。
FileUtils.copyDirectory(file, new File(destFilePath), new FileFilter() {
    @Override
    public boolean accept(File pathname) {
        if(pathname.isDirectory()) return true;
        else {
            boolean b1 = pathname.getName().endsWith(".txt");
            boolean b2 = pathname.getName().endsWith(".jpg");
            return b1 || b2;
        }
    }
});

2.IOUtils的使用

常用方法

将输入流或数组中的内容转换为字符串
toString(InputStream input, String encoding

String content = IOUtils.toString(new FileInputStream("d:/QQ/AAA/abc.txt"),"UTF-8");
System.out.println(content);

版权声明:本文为weixin_57138526原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。