Java最全JAVA IO流:字节流、字符流、缓冲流(1),Java面试题集2024版

架构学习资料

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

准备两个月,面试五分钟,Java中高级岗面试为何越来越难?

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

(一)BufferedOutputStream

构造方法如下:

| Constructor | 描述 |

| — | — |

| BufferedOutputStream(OutputStream out) | 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。 |

| BufferedOutputStream(OutputStream out, int size) | 创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。 |

从 BufferedOutputStream 构造方法可以知道,传递过去的参数是 OutputStream类型的,因此要使用缓冲输出流之前先要创建一个字节输出流FileOutputStream对象

常用的方法如下:

| Modifier and Type | 方法 | 描述 |

| — | — | — |

| void | flush() | 刷新缓冲输出流。 |

| void | write(byte[] b, int off, int len) | 从偏移量 off开始的指定字节数组写入 len字节到缓冲输出流。 |

| void | write(int b) | 将指定的字节写入缓冲的输出流。 |

这其中的write方法和FileOutputStream中的write方法用法大体上一样。

而flush()方法则是实现了一个刷新功能,因为输入的数据是存在一个缓冲区里面,若想吧缓冲区的数据存放到文件中,那么就需要用到flush方法,它可以刷新缓冲输入流,实现此功能。


package Stream;



import java.io.BufferedOutputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;



public class BufferedOutputStreamDemo01 {

    public static void main(String[] args) throws IOException {

        //创建字节输出缓冲流对象

        BufferedOutputStream bof = new BufferedOutputStream(new FileOutputStream("IO\\bof.txt"));

        //写入数据

        bof.write("Hello\r\n".getBytes());

        bof.write("World\r\n".getBytes());

        //刷新缓冲流

        bof.flush();

        //释放资源

        bof.close();

    }

}



改程序的运行结果是将Hello和World分别写进文件的两行,这时候就会感觉奇怪了,不是说要不说明是否追加写入的话默认不追加写入吗?那为什么这里还能写进两个字符串?

这是文件关闭(执行close方法)后再打开文件写入数据,原来数据保存,那才叫追加写入。但是这里从头到尾文件只打开一次,所以不是追加写入,只是在打开一个文件的情况下,进行写入数据。


(二)BufferedInputStream

构造方法如下:

| Constructor | 描述 |

| — | — |

| BufferedInputStream(InputStream in) | 创建一个 BufferedInputStream并保存其参数,输入流 in供以后使用。 |

| BufferedInputStream(InputStream in, int size) | 创建具有指定缓冲区大小的 BufferedInputStream ,并保存其参数,输入流 in供以后使用。 |

同样的,BufferedInputStream 的构造方法传递的参数类型是 InputStream 类型的数据,因此在创建这个BufferedInputStream 对象时,需要先构造一个 FileInputStream 对象,然后作为BufferedInputStream 对象构造方法的参数。

常用方法如下:

| Modifier and Type | 方法 | 描述 |

| — | — | — |

| void | close() | 关闭此输入流并释放与流相关联的任何系统资源。 |

| int | read() | 见 readInputStream的一般合同。 |

| int | read(byte[] b, int off, int len) | 从给定的偏移开始,将字节输入流中的字节读入指定的字节数组。 |

这些常用的方法的使用方法,与FileInputStream类中的没啥区别,用法大致相同


package Stream;



import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;



public class BufferedInputStreamDemo01 {

    public static void main(String[] args) throws IOException {

        //创建字节缓冲输入流对象

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("IO\\bof.txt"));



        //一次读取一个字节数据

        int by;

        while ((by = bis.read()) != -1){

            System.out.print((char) by);

        }



        //一次读取一个字节数组

        byte[] bys = new byte[1024];

        int len;

        while ((len = bis.read(bys)) != -1) {

            System.out.println(new String(bys, 0, len));

        }



        bis.close();

    }

}




四、字符流概论


为什么会出现字符流呢?

是因为如果读取文本数据时,如果文本数据中有中文,而中文是由多个字节构成的,那么字节流通过读取一个一个字节输出的方式显然是不行,这样输出的结果会是一串乱码。

此时字符流的优势就展现出来了,而字符流 = 字节流 + 编码表

一个汉字在不同的编码的存储是不一样的

  1. 如果是GBK编码,占用2个字节
  1. 如果是UTF-8编码,占用3个字节

由前面我们可以知道,String类中的getBytes方法可以使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中**,其中IDEA中默认的编码是UTF-8,**因此用它来解码一个汉字,则会得到三个字节。

String类中的getBytes方法是一个重载的方法,具体如下:

| Modifier and Type | 方法 | 描述 |

| — | — | — |

| byte[] | getBytes() | 使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中。 |

| byte[] | getBytes(String charsetName) | 使用命名的字符集将该 String编码为一系列字节,将结果存储到新的字节数组中。 |

因此我们可以使用第二个重载了的getBytes方法进行指定编码解码汉字


package Stream;



import java.io.UnsupportedEncodingException;

import java.util.ArrayList;

import java.util.Arrays;



public class getBytesDemo {

    public static void main(String[] args) throws UnsupportedEncodingException {

        String s = "中国";

        byte[] bys01 = s.getBytes();

        byte[] bys02 = s.getBytes("GBK");

        System.out.println("UTF-8解码结果:" + Arrays.toString(bys01));

        System.out.println("GBK解码结果:" + Arrays.toString(bys02));

        /*

        运行结果:

        UTF-8解码结果:[-28, -72, -83, -27, -101, -67]

        GBK解码结果:[-42, -48, -71, -6]

         */

    }

}



但是我们使用字节流也可以复制文本文件,文本文件也会有中文,但是却没问题,这是为什么呢?

原因是最终底层操作会自动进行字节拼接成中文,但是是如何识别是中文的呢?

其实,汉字在存储的时候,无论选择哪种编码存储,其第一个字节都是负数,因此只要是字节是负数就说明它是汉字。


(一)编码表

字符流涉及到编码方式,因此需要了解到编码表

基础知识

  1. 计算机中存储的信息都是用二进制表示的;

  2. 按照某种规则,将字符存储到计算机中,称为编码

  3. 将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码;

字符集

字符集是一个系统支持的所有字符的集合,包括国家文字,图形符号,数字等;

常见的字符集有:ASCII字符集、GBXXXX字符集、Unicode字符集

各个国家为了符合自己国家语言,然后设计出了一套属于自己国家的字符集,但是其他国家并没有它这套字符集,那么其他国家解码岂不是都是乱码???

其实并不然Unicode字符集的出现解决了这个现象,其中最为常用的就是UTF-8编码,互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码,它使用一至四个字节为每个字符编码。

必须强调的是采用哪种规则编码,就必须采用对应规则解码,否则会出现乱码!!!!


(二)OutputStreamWriter

Writer:字节输出流的抽象类

而 OutputStreamWriter 是继承 Writer 的子类

其构造方法如下:

| Constructor | 描述 |

| — | — |

| OutputStreamWriter(OutputStream out) | 创建一个使用默认字符编码的OutputStreamWriter。 |

| OutputStreamWriter(OutputStream out, String charsetName) | 创建一个使用命名字符集的OutputStreamWriter。 |

常用方法如下:

| Modifier and Type | 方法 | 描述 |

| — | :-: | — |

| void | close() | 关闭流,先刷新。 |

| void | flush() | 刷新流。 |

| void | write(char[] cbuf, int off, int len) | 写入字符数组的一部分。 |

| void | write(int c) | 写一个字符 |

| void | write(String str, int off, int len) | 写一个字符串的一部分。 |

这些方法的使用方法大体上与字节流差不多,值得注意的是write方法传递的参数可以直接传递字符数组,不用先解码成byte数组再传递过去。


package Stream;



import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStreamWriter;



public class OutputStreamWriterDemo01 {

    public static void main(String[] args) throws IOException {

        //创建对象

        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("IO\\osw.txt"));



        //1.写入字符

        osw.write('a');



        //2.写入字符串

        osw.write("\r\n中国\r\n");

        osw.flush();



        //3.字符数组

        char[] ch = {'a', 'b', 'c'};

        osw.write(ch);

        osw.write(ch, 0, 1);

        osw.flush();



        //4.写入一部分

        osw.write("HelloWorld", 0, 5);

        osw.flush();



        osw.close();

    }

}



需要注意的是:OutputStreamWriter的中的close有点特别,它是在关闭之前会先刷新,也就是说在执行释放资源的之前,其会先主席那个flush方法,达到先把数据存储在文本信息的结果再释放资源。


(三)InputStreamReader

Reader:字节输入流的抽象类

InputStreamReader 是继承了 Reader 的子类

其构造方法如下:

| Constructor | 描述 |

| — | — |

| InputStreamReader(InputStream in) | 创建一个使用默认字符集的InputStreamReader。 |

| InputStreamReader(InputStream in, String charsetName) | 创建一个使用命名字符集的InputStreamReader。 |

常用方法如下:

| Modifier and Type | 方法 | 描述 |

| — | — | — |

| void | close() | 关闭流并释放与之相关联的任何系统资源。 |

| int | read() | 读一个字符 |

| int | read(char[] cbuf, int offset, int length) | 将字符读入数组的一部分。 |


package Stream;



import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStreamReader;



public class InputStreamReaderDemo01 {

    public static void main(String[] args) throws IOException {

        //创建对象

        InputStreamReader isr = new InputStreamReader(new FileInputStream("IO\\osw.txt"));



        //读一个字符数据数据

        int ch;

        while ((ch = isr.read()) != -1){

            System.out.print((char) ch);

        }



        //一次读一个字符数组数据

        char[] chs = new char[1024];

        int len;

        while ((len = isr.read(chs)) != -1){

            System.out.println(new String(chs));

        }

    }

}



InputStreamReader的常用方法的使用大多与字节流类似


(四)字符流中的编码解码问题

在IDEA中默认的编码解码都是使用UTF-8编码来实现的

但是如果我们构建字符输出流对象 OutputStreamWriter 的时候指定使用其他字符集编码,比如指定使用GBK编码,这是后我们打开已经写入数据的txt文件中,我们会发现出现了乱码情况,这是为什么呢???

这是因为txt默认使用UTF-8编码进行解码,但是编码是使用GBK进行编码的,因此肯定会出现乱码情况。

这时候我们读取数据显示在屏幕上的时候,如果我们创建字符输入流对象 InputStreamReader 的时候,没有指定使用GBK编码进行解码,那么它会默认使用UTF-8编码进行解码,进而出现乱码的情况,若我们需要显示出正常的内容而不是乱码,我们需要执行GBK编码进行解析。

总而言之,我们规定了使用哪种规则进行编码,就要使用哪种规则进行解析,否则会乱码!!!!

(五)FileWrite 与 FileReader

在处理现实问题中,比如复制一个java文件,如果其中不涉及编码问题,即不需要指定某种编码规则进行编码和解码,那么为了简便,我们可以使用 OutputStreamWriter 的子类 FileWrite 、 InputStreamReader 的子类 FileReader

但是如果一旦涉及到编码问题,还得使用 OutputStreamWriter 和 InputStreamReader 进行处理文件!!!

FileWrite 的构造方法如下:

| Constructor | 描述 |

| — | — |

| FileReader(File file) | 创建一个新的 FileReader ,给出 File读取。 |

| FileReader(String fileName) | 创建一个新的 FileReader ,给定要读取的文件的名称。 |

由于 FileWrite 继承了 OutputStreamWriter ,所以 FileWrite 的常用方法的类型与用法与OutputStreamWriter一致

FileReader 的构造方法如下:

| Constructor | 描述 |

| — | — |

| FileWriter(File file) | 给一个File对象构造一个FileWriter对象。 |

| FileWriter(File file, boolean append) | 给一个File对象构造一个FileWriter对象。 |

| FileWriter(String fileName) | 构造一个给定文件名的FileWriter对象。 |

| FileWriter(String fileName, boolean append) | 构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。 |

同样,由于 FileReader 继承了 InputStreamReader ,所以 FileReader 的常用方法的类型与用法与InputStreamReader 一致


五、字符缓冲流概述


字符缓冲流主要是 BufferedWriter 与 BufferedReader, 两者分别继承两个抽象类 Writer 与 Reader ;

BufferedWriter :将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小,默认足够打,可用于大多数用途。

BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以接受默认大小,默认足够打,可用于大多数用途。


(一)BufferedWriter

BufferedWriter 字符缓冲输出流的构造方法如下:

| Constructor | 描述 |

| — | — |

| BufferedWriter(Writer out) | 创建使用默认大小的输出缓冲区的缓冲字符输出流。 |

| BufferedWriter(Writer out, int sz) | 创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。 |

从构造方法可知道,需要传递一个 Writer 类型的作为参数过去, 因此在使用字符缓冲输出流的时候,要先创建一个FileWriter对象

BufferedWriter 字符缓冲输出流的常用方法如下:

| Modifier and Type | 方法 | 描述 |

| — | — | — |

| void | close() | 关闭流,先刷新。 |

| void | flush() | 刷新流。 |

| void | newLine() | 写一行行分隔符。 |

| void | write(char[] cbuf, int off, int len) | 写入字符数组的一部分。 |

| void | write(int c) | 写一个字符 |

| void | write(String s, int off, int len) | 写一个字符串的一部分。 |

这里面的很多方法都与前面的类似,但是这有一个特有的方法 newLine 方法, 其作用是写一行行分隔符,也就是换行的意思。

从上面我们可以知道,不同的操作系统的换行符号不一样,比如window的换行符号是\r\n,但是Linux的换行符号是\n,如果手动添加换行符,如果在不同的系统可能达不到换行的效果,因此,newLine 方法的出现,很好的解决了在不同系统换行的问题!!!


package Stream;



import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;

import java.io.OutputStream;



public class BufferedWriterDemo {

    public static void main(String[] args) throws IOException {

        //创建字符缓冲流输出流对象

        BufferedWriter bw = new BufferedWriter(new FileWriter("IO\\bw.txt"));

        bw.write("Hello");

        bw.newLine();//换行

        bw.write("World");

        bw.close();

    }

}




(二)BufferedReader

字符缓冲输入流 BufferedReader构造方法如下:

| Constructor | 描述 |

| — | — |

| BufferedReader(Reader in) | 创建使用默认大小的输入缓冲区的缓冲字符输入流。 |

| BufferedReader(Reader in, int sz) | 创建使用指定大小的输入缓冲区的缓冲字符输入流。 |

从构造方法可知道,需要传递一个 Reader类型的作为参数过去, 因此在使用字符缓冲输入流的时候,要先创建一个FileReader对象

BufferedReader字符缓冲输入流的常用方法如下:

| Modifier and Type | 方法 | 描述 |

| — | — | — |

| void | close() | 关闭流并释放与之相关联的任何系统资源。 |

| int | read() | 读一个字符 |

| int | read(char[] cbuf, int off, int len) | 将字符读入数组的一部分。 |

| String | readLine() | 读一行文字。 |

这里面的很多方法都与前面的类似,但是其中有一个readLine的方法,可以一次读一行文字,然后返回一个String类型,这个方法十分实用


package Stream;



import java.io.BufferedReader;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;



public class BufferedReaderDemo {

    public static void main(String[] args) throws IOException {

        //创建对象

        BufferedReader br = new BufferedReader(new FileReader("IO\\bw.txt"));



        String line;



# 《MySql面试专题》

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/73fef75bcc696de74b9031ec575f0a5e.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/3acf1abbfc2e64b8c0a249aaf46a0736.webp?x-oss-process=image/format,png)

# 《MySql性能优化的21个最佳实践》

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/fe6e1f6c7b8df6bac528a53fe192efde.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/4a1d13529e5b12883c171481893f406f.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/cdcb6a05f685c8ca9e098f79cc98929a.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/a38a21199017f36434589c595af80fdd.webp?x-oss-process=image/format,png)

# 《MySQL高级知识笔记》

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/a0e712dbaca620b4d75301e1590183f0.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/3ec49a91c38a5e368cde4361c17524e1.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/16e68611dcbbc33406d0bff021271650.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/c23b6c7591317969b06ce95dfc6486fb.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/2f553be920a39dc23613c457daaacccc.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/77f7857923d81674b24d58d7ee9bcda0.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/9c93b9378bf0364034383dbd765e8e17.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/b0fae70dcc44a56b82a26dc93097b151.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/605520471bf2cee9f4ab5500fbba0434.webp?x-oss-process=image/format,png)

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/ad289bbabd169c5c84fa2f154dcaf0aa.webp?x-oss-process=image/format,png)

文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图

![全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好](https://img-blog.csdnimg.cn/img_convert/499d78b527f7c772cc1894a2b066db64.webp?x-oss-process=image/format,png)

**关注我,点赞本文给更多有需要的人**

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

XiP8yQ-1715305534321)]

[外链图片转存中...(img-9QMLKQ0O-1715305534322)]

[外链图片转存中...(img-q61X6NYR-1715305534322)]

# 《MySQL高级知识笔记》

[外链图片转存中...(img-pHPlgoRK-1715305534322)]

[外链图片转存中...(img-rrmGKRz9-1715305534323)]

[外链图片转存中...(img-4iWpcyEH-1715305534323)]

[外链图片转存中...(img-ktNXKVUG-1715305534323)]

[外链图片转存中...(img-Uw0AC6PE-1715305534323)]

[外链图片转存中...(img-RtFcMp3m-1715305534324)]

[外链图片转存中...(img-IZf3aE9v-1715305534324)]

[外链图片转存中...(img-48k5ZXvY-1715305534324)]

[外链图片转存中...(img-upFhU9aW-1715305534325)]

[外链图片转存中...(img-oM9Foo0b-1715305534325)]

文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图

[外链图片转存中...(img-jlGzyZRz-1715305534325)]

**关注我,点赞本文给更多有需要的人**

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值