黑马程序员——Java基础----IO(字节流、操作规律等)(2)

                    -----------android培训java培训、java学习型技术博客、期待与您交流!------------ 


                                                           IO(字节流、操作规律等)

一、概述

1、字符流:FileReader/FileWriter;BufferedReader/BufferedWriter

字节流:InputStream(读取)、OutputStream

*****字符流底层是字节流,一个中文字是两个字节,因此读取字节的时候需要先缓存在刷新(因为一个字节查表查不到)
2、为何不用进行刷流动作:
        因为字节流操作的是字节,即数据的最小单位,不需要像字符流一样要进行转换为字节。所以可直接将字节数据写入到指定文件中。
3InputStream特有方法:
        int available();//返回文件中的字节个数
注:可以利用此方法来指定读取方式中传入数组的长度,从而省去循环判断。但是如果文件较大,而虚拟机启动分配的默认内存一般为64M。当文件过大时,此数组长度所占内存空间就会溢出。所以,此方法慎用,当文件不大时,可以使用。



示例:


练习:复制一个图片



?????可以用字符流读取图片吗?
答:可以  但是读取的字符要去查表,因此可能不显示,要查编码表。
  不要拿字符流拷贝媒体文件

二、字节流的缓冲区:

      同字符流的缓冲区一样,是提高了字节流的读写效率。

1、读写特点:

        read():会将字节byte型值提升为int型值

        write():会将int型强转为byte型,即保留二进制数的最后八位。

2、原理:将数据拷贝一部分,读取一部分,循环,直到数据全部读取完毕。

        1)先从数据中抓取固定数组长度的字节,存入定义的数组中,再通过然后再通过read()方法读取数组中的元素,存入缓冲区。

        2)循环这个动作,直到最后取出一组数据存入数组,可能数组并未填满,同样也取出包含的元素。

        3)每次取出的时候,都有一个指针在移动,取到数组结尾就自动回到数组头部,这样指针在自增。

        4)取出的时候,数组中的元素在减少,取出一个,就减少一个,直到减到0即元素取完。

        5)当文件中的全部数据都被读取出时,read()方法就返回-1。

3、自定义读取字节流缓冲区

        需求:根据字节流缓冲区的原理,自定义一个字节流缓冲区。

注意:

        1、字节流的读一个字节的read方法为什么返回值类型不是byte,而是int。

       因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。

       所以,为了避免这种情况将读到的字节进行int类型的提升。并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。而在写入数据时,只写该int类型数据的最低8位。

        2、byte类型的-1提升为int类型时还是-1。原因:因为在bit8个1前面补的全是1导致的。如果在bit8个1前面补0,即可以保留原字节数据不变,又可以避免-1的出现。这时将byte型数据&0xff即255即可。

通过缓冲区演示MP3的复制:



 自定义方法,模拟字节流的缓冲区:

原理图:





以提升一个字节read的时候变成4个字节,写的时候以int形式往外写,write,那应该是4个字节码?

答:不是,因为,read提升,write强制转换

三、流的操作规律:

1、读取键盘录入
示例:



2、OutputStreamWriter:字符转字节

二、流操作规律

1、

        源:键盘录入。

        目的:控制台。

2、需求:想把键盘录入的数据存储到一个文件中。

        源:键盘

        目的:文件。

        使用字节流通向字符流的转换流(桥梁):InputStreamReader

3、需求:想要将一个文件的数据打印在控制台上。

        源:文件

        目的:控制台

        使用字符流通向字节流的转换流(桥梁):OutputStreamWriter

4、流操作的基本规律:

        最痛苦的就是流对象有很多,不知道该用哪一个。

通过三个明确来完成:

4.1   明确源和目的。

        源:输入流。InputStream  Reader

        目的:输出流。OutputStream  Writer

4.2   操作的数据是否是纯文本。

        是:字符流

        否:字节流

4.3   当体系明确后,再明确要使用哪个具体的对象。通过设备来进行区分:

        源设备:内存,硬盘,键盘

        目的设备:内存,硬盘,控制台

5、规律体现

5.1 将一个文本文件中数据存储到另一个文件中。复制文件。

        1)源:因为是源,所以使用读取流:InputStream和Reader

             明确体系:是否操作文本:是,Reader

              明确设备:明确要使用该体系中的哪个对象:硬盘上的一个文件。Reader体系中可以操作文件的对象是FileReader

              是否需要提高效率:是,加入Reader体系中缓冲区 BufferedReader.

              FileReader fr = new FileReader("a.txt");

              BufferedReader bufr = new BufferedReader(fr);

        2)目的:输出流:OutputStream和Writer

             明确体系:是否操作文本:是,Writer

              明确设备:明确要使用该体系中的哪个对象:硬盘上的一个文件。Writer体系中可以操作文件的对象FileWriter。

              是否需要提高效率:是,加入Writer体系中缓冲区 BufferedWriter

              FileWriter fw = new FileWriter("b.txt");

              BufferedWriter bufw = new BufferedWriter(fw);

练习:将一个图片文件中数据存储到另一个文件中。复制文件。要按照以上格式自己完成三个明确。

        1)源:输入流,InputStream和Reader

            是否是文本?否,InputStream

            源设备:硬盘上的一个文件。InputSteam体系中可以操作文件的对象是FileInputSteam

            是否需要提供效率:是,BufferedInputStream

              BufferedInputSteambis=newBufferedInputStream(newFileInputStream("c:/users/asus/desktop/1.jpg"));

        2)目的:输出流,OutputStream和Writer

             是否是文本?否,OutputStream

             源设备:硬盘上的文件,FileOutputStream

             是否需要提高效率:是,加入BufferedOutputStream

               BufferedOutputStreambos=newBufferedOutputStream(newFileOutputStream("c:/users/asus/desktop/2.jpg"));

5.2 需求:将键盘录入的数据保存到一个文件中。

        1)源:InputStream和Reader

              是不是纯文本?是,Reader

              设备:键盘。对应的对象是System.in。——为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。所以既然明确了Reader,那么就将System.in转换成Reader。用Reader体系中转换流,InputStreamReader

              InputStreamReaderisr = new InputStreamReader(System.in);

             需要提高效率吗?需要,BufferedReader

             BufferedReaderbufr = new BufferedReader(isr);

       2)目的:OutputStream  Writer

             是否是存文本?是!Writer。

             设备:硬盘。一个文件。使用 FileWriter。

             FileWriter fw = newFileWriter("c.txt");

           需要提高效率吗?需要。

            BufferedWriter bufw = new BufferedWriter(fw);

5.3   扩展:想要把录入的数据按照指定的编码表(UTF-8)(默认编码表是GBK),将数据存到文件中。

        目的:OutputStream  Writer

        是否是存文本?是!Writer。

        设备:硬盘上的一个文件。使用 FileWriter。——但是FileWriter是使用的默认编码表:GBK。而存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。所以要使用的对象是OutputStreamWriter。

        该转换流对象要接收一个字节输出流,而且还可以操作的文件的字节输出流:FileOutputStream

        OutputStreamWriter osw =new OutputStreamWriter(newFileOutputStream("d.txt"),"UTF-8");

        需要高效吗?需要,BufferedWriter

        BufferedWriter bufw = new BufferedWriter(osw);

记住:

       转换流什么使用?

       字符和字节之间的桥梁。通常,涉及到字符编码转换时,需要用到转换流。

练习:将一个文本数据打印在控制台上。要按照以上格式自己完成三个明确。

        1)源:InputStreamReader

            是文本?是:Reader

            设备:硬盘。上的文件:FileReader

            是否需要提高效率?是:BufferedReader

             BufferedReader br=new BufferedReader(newFileReader("1.txt"));

       2)目的:OutputStream Writer

            是文本?是:Writer

            设备:控制台。对应对象System.out。由于System.out对应的是字节流,所以利用OutputSteamWriter转换流

            是否提高效率?是:BufferedWriter

              BufferedWriter bw =new BufferedWriter(newOutputStreamWriter(system.out));





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值