Java中的I/O讲解(超容易理解)(中篇)

如果想观看更多Java内容 可上我的个人主页关注我,地址

子逸爱编程-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/a15766649633?spm=1000.2115.3001.5343

使用工具 IntelliJ IDEA Community Edition 2023.1.4

使用语言 Java8 

代码能力快速提升小方法,看完代码自己敲一遍,十分有用 

目录

1.字节流

1.1 字节输出流

1.1.1 字节输出流基类:OutputStream

1.1.2 字节输出流FileOutputStream类 

1.1.3 字节输出流贯穿示例 

1.2 字节输入流

1.2.1 字节输入流基类:InputStream 

1.2.2 字节输入流FileInputStream类

1.2.3 字节输入流贯穿示例 

2.字符流

2.1 字符输出流

2.1.1 字符输出流基类:Writer 

2.1.2 字符输出流FileWriter类 

2.1.3 字符输出流贯穿示例 

2.2 字符输入流

2.2.1 字符输入流基类:Reader

2.2.2 字符输入流FileReader

2.2.3 字符输入流示例

3.字符缓冲流

3.1 字符缓冲流基本概念 

3.2 字符缓冲输出流 

3.2.1 字符缓冲输出流基本概念

3.2.2 字符缓冲输出流贯穿示例

3.3 字符缓冲输入流 

3.3.1 字符缓冲输入流基本概念 

3.3.2 字符缓冲输入流贯穿示例 


 

1.字节流

java.io包中的流按存储单元分类主要有字节流和字符流两大类,两类都具有输入/输出操作。它们各种的基类如下所示,这些基类均为抽象类;

字节流主要操作对时byte类型数据,其基类就是OutputStream类和InputStream类;

1.1 字节输出流

1.1.1 字节输出流基类:OutputStream

OutputStream类为抽象类,必须使用该类的子类进行实例化对象。如果需要操作文件,则使用FileOutputStream实例化。OutputStream类中的主要操作方法如下: 

主要操作方法
    void close()

        关闭输出流;
    void flush()
        刷新缓冲区;
    void write(byte[] b)
        将每个byte数组写入数据流;
    void write(byte[] b,int off,int len)
        将每个指定范围的byte数组写入数据流;
    void write(int b)
        将一个字节数据写入数据流;

1.1.2 字节输出流FileOutputStream类 

在实际应用中,通常使用OutputStream类的FileOutputStream子类想文本文件写入数据,常用的构造方法如下: 

构造方法:

FileOutputStream(File file)

  • 用于创建向指定File对象写数据的文件输出流
  • file:指定目标文件的对象

FileOutputStream(String name)

  • 用于创建向指定路径的文件写数据的文件输出流
  • name:指定目标文件的路径字符串

FileOutputStream(String name,boolean append)

  • 创建一个向指定路径的文件写入数据的文件输出流
  • name:指定目标文件的路径字符串
  • append:表示是否在文件末尾追加数据,若为true则表示可以在文件末尾追加数据

前两种构造方法在向文件写数据时将覆盖文件中原有的内容。另外在使用FileOutputStream类的构造方法创建对象时,如果对应的文件不存在,就会新建一个文件。如果参数file或name表示的文件路径是一个目录(或不存在这个目录),则会抛出FileNotFoundException(无法找到文件异常)。 

1.1.3 字节输出流贯穿示例 

示例代码:

public static void main(String[] args)  {
        OutputStream outputStream= null;
        try {
            //第一步 创建对象,第一个参数是路径,第二个可写可不写,为true的话就可以在末尾继续添加值,false或不写的话就直接覆盖原来的值
            outputStream = new FileOutputStream("./test/test.txt",true);//如果参数中的文件不存在就会自动帮你创建一个,但是盘符不能有误(会发生无法找到文件异常)
            //第二步 创建需要添加的数据
            String str="I Love Java!";
            //第三步 把数据变为字节(因为这个是字节流的)
            byte[] arr=str.getBytes();
            //第四步 使用write方法添加进去,第一个参数是数据源 第二个从第0个字节开始,第三个到最后结束(不加后面两个会打出来很多空格)
            outputStream.write(arr,0,arr.length);
            System.out.println("数据添加成功!");
            outputStream.close();
        } catch (FileNotFoundException e) {
            System.out.println("文件没找到不好意思,请联系管理员");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

执行两次后指定的文本文件中将出现两句I Love Java!

1.2 字节输入流

1.2.1 字节输入流基类:InputStream 

既然可以使用OutputStream类向文件写数据,那么也可以通过InputStream类从文件中读数据。InputStream同样是抽象类,该类中定义的主要方法如下:

常用方法:
    int read()
        读取一个字节数据;
    int read(byte[] b)
        将数据读取到字节数组中;
    int read(byte[] b,int off,int len)
        从输入流中读取最多len长度的字节,将其保存到字节数组中,保存的位置从off开始;
    void close()
        关闭输入流;
    int available()
        返回输入流读取的字节数 ;

1.2.2 字节输入流FileInputStream类

在实际开发中,通常使用InputStream类的FileInputStream子类实现文本文件内容的读取,其常用的构造方法如下所示:

构造方法:
    FileInputStream(File file)

  • 用于创建从指定File对象读取数据的文件输入流
  • file:指定目标文件数据源对象

    FileInputStream(String name)

  • 用于创建从指定路径的文件读取数据的文件输入流
  • name"指定目标文件数据源路径字符串 

1.2.3 字节输入流贯穿示例 

单字节输入流 

示例代码 

public static void main(String[] args) {
        //单字节读取,不可读取中文
        try {
            //第一步 创建对象,取到路径
            InputStream inputStream=new FileInputStream("./test/test.txt");
            //第二步 返回一个int值
            int data=inputStream.read();
            System.out.println("可读取的字节数:"+ inputStream.available());
            while (data!=-1){//如果字节跑完了,它的值就会变成-1
                System.out.print((char)data);//翻译二进制代码
                data=inputStream.read();//返回一个int值,返回-1就表示没有了
            }
            inputStream.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

运行结果 

 

多字节输入流

示例代码 

public static void main(String[] args) {
        //多字节读取,可读取中文
        try {
            //第一步 获取路径
            InputStream inputStream=new FileInputStream("./test/test.txt");
            //第二步 搞一个存字节的数组
            byte[] arr=new byte[3];
            //第三部 每次读取3个字节,就是存字节的那个数组长度,然后存到字节数组中
            int data=inputStream.read(arr);
            //第四步 判断代码是否打印完毕,打印完毕就退出循环
            while (data!=-1){
                System.out.print(new String(arr,0,data));//打印格式 new String(字节数组,从哪个下标开始,到哪里结束);new String代表转String类型
                data=inputStream.read(arr);//返回一个int值,返回-1就表示没有了
            }
            inputStream.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

运行结果 

 

 一般使用字节输入流来读取二进制文件,不适合文本文件;

2.字符流

在Java中,GBK编码方式一个中文字符占两个字节,但是现在是UTF编码方式,所以一个中文字符占3个字节。如果用字节流处理文本文件,则程序内部需要将字节转换成字符,降低了执行效率,所以当输入和输出文本文件时,尽量使用字符流。Java提供了Writer类和Reader类来操作字符;

2.1 字符输出流

2.1.1 字符输出流基类:Writer 

 Writer类是字符输出流的抽象基类,Writer类中定义的常用方法如下所示:

常用方法
    void write(String str)

        将str字符串中包含的字符输出到输出流中;
    void write(String str,int off,int len)
        奖字符串中从off位置开始、长度为len的字符输出到输出流中;
    void close()
        关闭输出流;
    void flush()
        刷新输出流;

2.1.2 字符输出流FileWriter类 

  • FileWriter类是Writer类常用的子类,使用该类可以以字符为数据处理单元向文本文件中写数据。
  • 创建该子类对象的方法与字节输出流的创建方法差不多 ;

2.1.3 字符输出流贯穿示例 

示例代码 

public static void main(String[] args) {
        //字符输出流示例
        Writer writer = null;
        try {
            //第一步 创建文件
            writer = new FileWriter("./test/Character.txt");
            //第二步 编写输出内容
            writer.write("预测未来的最好办法就是创造未来!");
            //第三步 把缓存中的数据塞给对应输出文件
            writer.flush();
            System.out.println("添加成功!");
        } catch (IOException e) {
            throw new RuntimeException(e);

        } finally {
            try {
                //第四步 关闭连接
                writer.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

 运行该类可以在输出的文本文档中打印"预测未来的最好办法就是创造未来!"; 

在以上代码中,使用了flush()方法清空流。通俗的说,把FileWriter对象比作排水的水管,将数据写入文本文件中的过程类似于将水通过水管抽取到其他容器的过程,如果在抽取的动作结束之后立即关闭水管,那么水管中有可能存在残留的水没有排干净的情况,这时还需要一个外力清空水管中的残留水,这个清空水管的操作,就类似使用flush()方法清空输出流FileWriter,它可以强制将其中残余的数据写入文本文件中,这样,才算完成全部数据的写操作,这时再使用close()方法关闭流。 

2.2 字符输入流

2.2.1 字符输入流基类:Reader

Reader类是字符输入流的基类,它是抽象类,Reader类的常用方法如下:

常用方法
    int read()

从输入流中读取单个字符,返回所读取的字符数据;
    int read(char[] c)
从输入流中最多读取c.length个字符数据并将其存储在字符数组c中,返回实际读取的字符数;
    int read(char[] c,int off,int len)
从输入流中最多读取len个字符数据并将其存储在字符数组c中。
在存入数组c中时,并不是从数组起点开始的,而是从off位置开始的,返回实际读取的字符数 ;

2.2.2 字符输入流FileReader

  • Reader类同样是抽象类,可以使用其子类FileReader创建对象。
  • 创建该子类对象的方法与字节输入流的创建方法差不多 ;

2.2.3 字符输入流示例

示例代码 

public static void main(String[] args) {
        //字符输入流示例
        Reader reader = null;
        try {
            //第一步 获取路径
            reader = new FileReader("./test/Character.txt");
            //第二步 搞一个存字符的数组
            char[] ch=new char[1024];
            //第三部 每次读取1024个字符,就是存字符的那个数组长度,然后存到字符数组中
            int data=reader.read(ch);
            //第四步 判断代码是否打印完毕,打印完毕就退出循环
            while(data>0){
                System.out.println(new String(ch,0,data));
                data=reader.read(ch);//返回一个int值,比0小就表示没有了
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                //第五步 关闭连接
                reader.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

 运行结果

字符输入流的示例与字节输入流的使用方法十分相似(几乎一模一样); 

3.字符缓冲流

3.1 字符缓冲流基本概念 

前面介绍的IO流全部属于节点流,能够存储介质(如磁盘、文件等)直接进行数据交互。为提供读写数据的执行效率,java.io包提供了缓冲流,缓冲流属于处理流。下面以字符缓冲流为例介绍缓冲流的用法。

使用缓冲字符流就像是一个人本来直接去水龙头下洗头的,有了缓冲之后就像是拿了水桶去把水接满然后再洗头,就是你先存到缓冲区,然后刷新缓冲区时就执行出来(输入流不用刷新缓冲区);

如果缓冲了就得用缓冲的对象来点方法,由于BufferedWriter是Writer的子类,所以可以调用Writer的方法,BufferedReader也是如此。

字符缓冲流就等于给字符流上buff;

3.2 字符缓冲输出流 

3.2.1 字符缓冲输出流基本概念

BufferedWriter类是Writer类的子类,BufferedWriter类可以把一批数据写到缓冲区,默认情况下,只有在缓冲区满的时候,才会把缓冲区的数据真正写到目的地,这样能减少物理写数据的次数(增加次数会减少磁盘的寿命),从而提高I/O操作的执行效率。BufferedWriter类的常用构造方法如下所示: 

BufferedWriter(Writer out)//创建一个缓冲字符输出流

方法
    newLine()     增加换行符 

3.2.2 字符缓冲输出流贯穿示例

示例代码 


        //字符缓冲输出流
        BufferedWriter reader = null;
        try {
            //第一步 创建字符流对象
            Writer w = new FileWriter("./test/music.txt");
            //第二步 给字符流对象缓冲
            reader = new BufferedWriter(w);
            //第三步 添加数据
            reader.write("身骑白马!");
            //第四步 刷新缓冲区(把缓冲区的数据添加到输出文件中)
            reader.flush();
            System.out.println("添加成功!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                //第五步 判断是否为空,不为空就关闭连接
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                System.out.println("关闭出现异常");
            }
        }
    }

 以上代码输出了一个“身骑白马”到输出文档文件中;

3.3 字符缓冲输入流 

3.3.1 字符缓冲输入流基本概念 

BufferedReader类是Reader的子类,它与FileReader类的区别在于BufferedReader类有缓冲区,它可以先把一批数据读到缓冲区中,接下来的读操作都是从缓冲区内获取数据,避免名称都从数据源读取数据进行字符编码转换,从而提高读取操作的效率。BufferedReader的常用构造方法如下:

BufferedReader(Reader in)

方法
readLine()

  • readLine()方法按行读取内容,最后利用while循环将读取的内容输出到控制台中,跟Reader的read()方法差不多 

3.3.2 字符缓冲输入流贯穿示例 

 示例代码

public static void main(String[] args) {
        //字符缓冲输入流
        BufferedReader bf = null;
        try {
            //第一步 创建输入流对象
            Reader r = new FileReader("./test/music.txt");
            //第二步 缓冲输入流对象
            bf = new BufferedReader(r);
            //第三步 获取数据,每次获取一行数据
            String data = bf.readLine();
            while (data != null) {
                //第四步 循环打印数据,不为空就打印
                System.out.println(data);
                //第五步 给数据进行迭代
                data = bf.readLine();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                //第六步 判断是否为空,不为空就关闭连接
                if (bf != null) {
                    bf.close();
                }
            } catch (IOException e) {
                System.out.println("关闭发生异常");
            }
        }
    }

运行结果 

 

  • 29
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值