教你完全理解IO流里的 read(),read(byte[]),read(byte[],int off,int len)以及write

好的我们先来讲它们的作用,然后再用代码来实现给大家看


  • read():

    1.从读取流读取的是一个一个字节

    2.返回的是字节的(0-255)内的字节值

    3.读一个下次就自动到下一个,如果碰到-1说明没有值了.


  • read(byte[] bytes)

    1.从读取流读取一定数量的字节,如果比如文件总共是102个字节

    2.我们定义的数组长度是10,那么默认前面10次都是读取10个长度

    3.最后一次不够十个,那么读取的是2个

    4.这十一次,每次都是放入10个长度的数组.



  • read(byte[] bytes,int off ,int len)

    1.从读取流读取一定数量的字节,如果比如文件总共是102个字节

    2.我们定义的数组长度是10,但是这里我们写read(bytes,0,9)那么每次往里面添加的(将只会是9个长度),就要读12次,最后一次放入3个.

    3.所以一般读取流都不用这个而是用上一个方法:read(byte[]);


下面讲解write


  • write(int i);

    直接往流写入字节形式的(0-255)int值.


  • write(byte[] bytes);

    往流里边写入缓冲字节数组中的所有内容,不满整个数组长度的”空余内容”也会加入,这个下面重点讲,


    • write(byte[] bytes,int off,int len);

      1.这个是更严谨的写法,在外部定义len,然后每次len(为的是最后一次的细节长度)都等于流往数组中存放的长度

      2.如上述read(bytes),前面每次都放入十个,第十一次放入的是2个,如果用第二种write(bytes),将会写入输出流十一次,每次写入十个长度,造成后面有8个空的,比原来的内容多了

      3.所以用write(byte[] bytes,int off,int len);就不会出现多出来的空的情况,因为最后一次len不同

    下面是详细的代码
    public class Test{
        public static void main(String[] args) throws Exception {
    
            UseTimeTool.getInstance().start();
    
            FileInputStream fis = new FileInputStream("D:\\1.mp3");
            FileOutputStream fos = new FileOutputStream("D:\\1copy.mp3");
            //(PS:一下3个大家分开来写和测试,为了方便我都列出来了)
            /*--------------不使用缓冲--------------*/
            //如果不缓冲,花了差不多14"秒"
            int len = -1;
            while ((len = fis.read()) != -1) {
                //这里就不是长度的问题了,而是读取的字节"内容",读到一个写一个,相当慢.
                System.out.println("len : "+ len);  
                fos.write(len);
            }
    
            /*--------------使用缓冲--------------*/
            //缓冲方法复制歌曲用了不到20"毫秒"
            //创建一个长度为1024的字节数组,每次都读取5kb,目的是缓存,如果不用缓冲区,用fis.read(),就会效率低,一个一个读字节,缓冲区是一次读5000个
            byte[] bytes = new byte[1024*5];
            //每次都是从读取流中读取(5k)长度的数据,然后再写到文件去(5k的)数据,注意,每次读取read都会不同,是获取到下一个,直到后面最后一个.
            while (fis.read(bytes)!=-1) {
                //write是最追加到文件后面,所以直接每次添5K.
                fos.write(bytes);        
            }
            /*--------------解释len--------------*/
            //告诉你为什么用len
            byte[] bytes = new byte[1024*5];
            int len = -1;
            //解释这个fis.read(bytes)的意思:从读取流"读取数组长度"的数据(打印len可知),并放入数组
            while ((len = fis.read(bytes,0,1024)) != -1) {
                //虽然数组长度的*5,但是这里我们设置了1024所以每次输出1024
                System.out.println("len : "+ len);
                //因为每次得到的是新的数组,所以每次都是新数组的"0-len"
                fos.write(bytes,0,len);
            }
    
            fis.close();
            fos.close();
            UseTimeTool.getInstance().stop();
        }
    }
       
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    为了方便大家,也给大家一个统计时间的工具类

    class UseTimeTool {
        private static UseTimeTool utt = new UseTimeTool();
        private UseTimeTool() {
        }
        public static UseTimeTool getInstance() {
            return utt;
        }
        private long start;
        public void start() {
            start = System.currentTimeMillis();
        }
        public void stop() {
            long end = System.currentTimeMillis();
            System.out.println("所用時間 : " + (end - start) + "毫秒");
        }
    }
       
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    好了最后一个:len问题 最后多出数组不满的部分我特再写一个出来给大家分析

    首先,文本的内容是 
    这里写图片描述

    public class Test{
        public static void main(String[] args) throws Exception {
    
            UseTimeTool.getInstance().start();
            FileInputStream fis = new FileInputStream("D:\\a.txt");
            FileOutputStream fos = new FileOutputStream("D:\\acopy.txt");
       
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    不使用len:

    byte[] bytes = new byte[1024*5];
            while (fis.read(bytes)!=-1) {
                fos.write(bytes);        
            }
       
       
    • 1
    • 2
    • 3
    • 4

    得到的效果: 
    这里写图片描述 
    发现后续后很多的空部分,所以说不严谨


    使用len:

    byte[] bytes = new byte[1024*5];
            int len = -1;
            while ((len = fis.read(bytes,0,1024)) != -1) {
                fos.write(bytes,0,len);
            }
       
       
    • 1
    • 2
    • 3
    • 4
    • 5

    得到的效果 
    这里写图片描述 
    和原来一模一样,讲了那么多就是希望能帮助大家真正的理解.

    原文:http://blog.csdn.net/nzfxx/article/details/51802017
  • 20
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java中的IO流分为输入流和输出流,其中输入流用于读取数据,输出流用于写入数据。我们可以通过使用Java IO流来读取或写入文件、网络通信、内存缓冲区等。下面分别对Java IO流中的输入流和输出流进行详细讲解。 1. Java输入流 Java中的输入流用于读取数据,分为字节输入流和字符输入流两种。 字节输入流:InputStream InputStream是Java中所有字节输入流的父类,主要提供了读取字节的方法,包括: - int read():读取一个字节的数据并返回,如果已经到达输入流的末尾,则返回-1; - int read(byte[] b):读取b.length个字节的数据,并存储到数组b中,返回实际读取的字节数,如果已经到达输入流的末尾,则返回-1; - int read(byte[] b, int off, int len):读取len个字节的数据,并存储到数组b中从off位置开始的地方,返回实际读取的字节数,如果已经到达输入流的末尾,则返回-1。 字符输入流:Reader Reader是Java中所有字符输入流的父类,主要提供了读取字符的方法,包括: - int read():读取一个字符并返回,如果已经到达输入流的末尾,则返回-1; - int read(char[] c):读取c.length个字符的数据,并存储到数组c中,返回实际读取的字符数,如果已经到达输入流的末尾,则返回-1; - int read(char[] c, int off, int len):读取len个字符的数据,并存储到数组c中从off位置开始的地方,返回实际读取的字符数,如果已经到达输入流的末尾,则返回-1。 2. Java输出流 Java中的输出流用于写入数据,分为字节输出流和字符输出流两种。 字节输出流:OutputStream OutputStream是Java中所有字节输出流的父类,主要提供了写入字节的方法,包括: - void write(int b):写入一个字节的数据; - void write(byte[] b):写入数组b中所有的字节数据; - void write(byte[] b, int off, int len):写入数组b中从off位置开始的len个字节数据; - void flush():刷新该流的缓冲区,确保所有缓存的字节都被写出到目标设备中; - void close():关闭输出流。 字符输出流:Writer Writer是Java中所有字符输出流的父类,主要提供了写入字符的方法,包括: - void write(int c):写入一个字符; - void write(char[] c):写入数组c中所有的字符数据; - void write(char[] c, int off, int len):写入数组c中从off位置开始的len个字符数据; - void flush():刷新该流的缓冲区,确保所有缓存的字符都被写出到目标设备中; - void close():关闭输出流。 以上就是Java IO流的详细讲解,希望对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值