黑马程序员_io理解的内容

本文详细解析了IO流关闭机制中的close()方法作用,阐述了字符流与字节流在操作底层系统资源时的区别,特别是字符流使用底层系统缓冲区的原因以及如何刷新缓冲区以确保数据正确写入。同时,文章还对比了自定义缓冲区(如BufferedInputStream与BufferedOutputStream)与普通缓冲区(如BufferedReader和BufferedWriter)的特性,并讨论了使用字符流进行二进制文件复制时存在的问题。最后,文章介绍了不同类型的输出流(如FileWriter、OutputStreamWriter、PrintWriter等)如何将字符转换为字节并最终写入文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 ------- android培训java培训、期待与您交流! ----------

Io中关闭流close()方法是为了释放掉十分有限的操作系统资源。由于输入输出要调用底层的系统资源。

 

调用输出流(FileWriter)的writer方法的时候,并没有将数据写入到目的地中,而是写到了内存当中(流的缓冲区中),也可以理解为其实写到了流中,下一步我们就是将这些内存中(或流中)的数据写到目的地中,调用flush方法,将清空输入流,也就是将所有缓冲的数据发送到目的地。 注意,这里使用的缓冲区是底层系统提供的缓冲区.

字符流使用底层系统提供的缓冲区的原因:字符流它其实是一样走的字节,但是需要将字节临时的存起来,比方说,我读一个字符(占两个字节),我不能从文件中直接读一个字节,因为那样只能读半个中文,也就是将多个字节存放到这个系统提供的缓冲区中,然后使用编码表去对照这个系统缓冲区中的字节数据,去取出相应的字符。这就是InputStreamWriter对象做的事情。所以需要刷新

而对于字节流来说,没有使用这个缓冲区。因为无需转换。所以不需要刷新。

 

而对于自己创建的缓冲区来说:

BufferedInputStream与 BufferedOutputStream

BufferedReader 和BufferedWriter 类

 

它们内部实现了一个数组,先将数据放到这个数组中,然后一遍写到文件中(当然,对于字符缓冲区来说,还需要经过系统提供的缓冲区去编码),在读文件的时候,调用了fill()先将文件中的数据存储到这个数组中,然后再去操作数据的时候,从数组中直接拿就可以,不用每次取数据都去文件中取。如果缓冲区去完,则再去调用fill装满缓冲区。这样就可以对这个数组进行操作了,可以方便的取出一行数据,在数组中判断标志位。

 

而就在字符写入到这个底层缓冲区的时候,提供了字符编码的转换。。。

 

对于字符流中底层缓冲区,调用flush()的时候,将底层缓冲区刷新后写入文件数据。

而Io输出流中的 flush()方法的作用:

被置于缓冲区中的数据,是为了用更大的包的形式传递的字符(节省了系统资源,不必每次输入都调用底层资源一个个的去写入)在关闭输出流时候都将被送出。

而flush()的作用就是清空输出流,也就是将所有缓冲中的数据发送到目的地

 

 

其实无论字符流还是字节流,底层都是使用字节流的形式往相应的文件对象中写入输入,仅仅是字符流封装了字节流

public FileWriter(String fileName) throws IOException {
        super(new FileOutputStream(fileName));
}

public OutputStreamWriter(OutputStream out) {
        super(out);
        try {
            se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
        } catch (UnsupportedEncodingException e) {
            throw new Error(e);
        }
    }


其实就是将这个字符流转换为一个字节流,而将这个字节流转成一个转换流的形式对数据进行写出。

 

而在字符流输出的时候,也是使用的字节的方式输出。仅仅是提供了编码转换。

对于PrintWirter,来说,它的底层调用了write(s)

public void println(String x) {
        synchronized (lock) {
            print(x);
            println();
        }
    }
public void print(String s) {
        if (s == null) {
            s = "null";
        }
        write(s);
}


write的调用,如果PrintWriter在构造的时候传入了一个OutputStream,则将这个OutputStream利用OutputStreamWriter转成字符流,然后再调用其上的write方法。

public PrintWriter(OutputStream out, boolean autoFlush) {
        this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);

        // save print stream for error propagation
        if (out instanceof java.io.PrintStream) {
            psOut = (PrintStream) out;
        }
}

而对于普通的字符流来说,PrintWriter调用其上的writer即可。

 

不能使用字符流去对二进制文件进行复制:

原因:由于字符流要对二进制文件进行转码,可能对应的字节在编码表中不存在,故生成形如???的字符,再去转码的时候,就不知道该怎么去将这些码转换成为二进制数据了。


当我们使用字节流去一个个的读取数据的时候,特别要注意,当某个二进制资源的格式为11111111-1010101001010101010010101也就是这种形式时候,由于第一个字节转成int类型为-1,所以就停止读了,必须要通过方法去解决。也就是为什么read方法返回一个int类型而不是byte类型的原因。

Byte  -1----->int  -1  但是将一个字节变成了4个字节去存放。为了避免读到的数据-1和结束标记相同,就将这个数据(-1)的字节前边补0

 

也就是将读取到的数据(-1)变成了0000000000000000 00000000 1111111

从而返回的数据就不是-1了,而是其他的一个int数字,当我通过write写这个数据的时候,将这个int数据00000000 00000000 00000000 1111111传入到一个write(int a)的方法中写入,这个函数将前三个字节忽略,完成了数据的转换。

C++本科毕业设计-ROS机械臂上位机源码(下载即用),个人经导师指导并认可通过的高分设计项目,评审分98分,项目中的源码都是经过本地编译过可运行的,都经过严格调试,确保可以运行!主要针对计算机相关专业的正在做大作业、毕业设计的学生和需要项目实战练习的学习者,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源码(下载即用)C++本科毕业设计-ROS机械臂上位机源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值