博客信息

IO流之字节流(InputStream、OutputStream、自定义字节流缓冲区)

发布时间:『 2019-06-11 10:57』  博客类别:java基础  阅读(738)

InputStreamOutputStream

字节输出流为啥不要刷新缓冲区呢?

因为字节流操作的是字节,是内存中存储数据最小的单元,可以支持读一个取一个;

为啥字符输出流要刷新缓冲区?

因为一个字符两个字节,字符流底层调用了字节流,只不过加了编码表,读出一个字节在对应的编码表中是找不到对应的字符的,所以需要当读取到足够的字节时,刷新 一个缓冲区,才能将原有的字符给读取出来;

package com.javaxl.io.byteStream;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author 小李飞刀
 * @site www.javaxl.com
 * @company
 * @create  2019-06-11 19:39
 */
public class FileStreamDemo {
    public static void main(String[] args) throws IOException {
//        单个字节单个字节进行读取
//        read_1();
//        一次读取1024个字节
//        read_2();
//        一次读取流文件对应的大小  的字节(慎用,如果读取的文件过大,那么会内存溢出)
        read_3();

        write();
    }

    public static void read_1() throws IOException {
        FileInputStream fis = new FileInputStream("C:\\fos.txt");
        int by = 0;
        while ((by=fis.read())!=-1){
            System.out.println((char)by);
        }
        fis.close();
    }

    public static void read_2() throws IOException  {
        FileInputStream fis = new FileInputStream("C:\\fos.txt");
        byte[] bbuf = new byte[1024];
        int len = 0;
        while ((len=fis.read(bbuf))!=-1){
            System.out.println(new String(bbuf,0,len));
        }
        fis.close();
    }

    public static void read_3() throws IOException  {
        FileInputStream fis = new FileInputStream("C:\\fos.txt");
        byte[] bbuf = new byte[fis.available()];
        int len = 0;
        while ((len=fis.read(bbuf))!=-1){
            System.out.println(new String(bbuf,0,len));
        }
        fis.close();
    }

    public static void write() throws IOException  {
        FileOutputStream fis = new FileOutputStream("C:\\fos.txt");
        fis.write("abcde".getBytes());
        fis.write("\r\n".getBytes());
        fis.write("fgh".getBytes());
        fis.write("\r\n".getBytes());
        fis.write("ij".getBytes());
        fis.close();
    }
}


复制一个图片

package com.javaxl.io.byteStream;

import java.io.*;

/**
 * @author 小李飞刀
 * @site www.javaxl.com
 * @company
 * @create  2019-06-11 19:39
 *
 * 思路:
 * 1、用字节读取流对象和图片相关联
 * 2、用字节写入流对象创建一个图片文件,用于存储获取到的图片数据
 * 3、通过循环读写,完成数据的存储
 * 4、关闭资源
 */
public class FileStreamDemo2 {
    public static void main(String[] args) throws IOException {
//        不使用缓冲流读取
//        copy_1();
//        使用缓冲流读取
        copy_2();
    }

    public static void copy_1() throws IOException {
        FileInputStream fis  = new FileInputStream("C:\\6.jpg");
        FileOutputStream fos = new FileOutputStream("C:\\6_copy.jpg");
        byte[] bbuf = new byte[1024];
        int len = 0;
        while ((len = fis.read(bbuf))!=-1){
            fos.write(bbuf,0,len);
        }
        fis.close();
        fos.close();
    }

    public static void copy_2() throws IOException  {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\6.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\6_copy.jpg"));
        byte[] bbuf = new byte[1024];
        int len = 0;
        while ((len = bis.read(bbuf))!=-1){
            bos.write(bbuf,0,len);
        }
        bis.close();
        bos.close();
    }

}


自定义字节流缓冲区

进制转换的一个应用

思想

1、在自定义字节流缓冲区中定义一个数组

2、通过FileInputStream读取数据到字节数组中;

3、通过自定义缓冲流中的read方法一个个从数组中读取出来,读取的同时指针后移,计数器减1

小李飞刀_IO流


package com.javaxl.io.byteStream;

import java.io.*;

/**
 * @author 小李飞刀
 * @site www.javaxl.com
 * @company
 * @create  2019-06-11 20:23
 */
public class MyBufferedInputStreamDemo {
    public static void main(String[] args) throws IOException {
        MyBufferedInputStream bis = new MyBufferedInputStream(new FileInputStream("C:\\6.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\6_copy2.jpg"));
        int by = 0;
        while ((by = bis.read())!=-1){
            bos.write(by);
        }
        bis.close();
        bos.close();
    }
}

class MyBufferedInputStream {
    private InputStream in;

    private byte[] bbuf = new byte[1024];

    private int pos = 0;//数组下标指针
    private int count = 0;//数组中字节的个数

    public MyBufferedInputStream(InputStream in) {
        this.in = in;
    }

    public int read() throws IOException {
        if (count == 0) {
//            意味着字节缓冲区数组中字节读完了,需要从硬盘中读取数据存放到缓冲区数组中
            count = in.read(bbuf);
            if (count < 0)//意味着硬盘中的数据也读完了
                return -1;

            pos = 0;
            byte b = bbuf[pos];

            pos++;
            count--;
//            byte是一个字节,int是四个字节,一个八位的二进制数,提升到32位的二进制位会出现精度丢失,所以需要与上一个255
//            详情参考下面图解
            return b & 255;

        } else  if (count > 0) {
            byte b = bbuf[pos];

            pos++;
            count--;
            return b & 0xff;
        }
        return -1;
    }

    public void close() throws IOException {
        in.close();
    }
}



小李飞刀_IO流

Read方法在做提升,write方法向下强制转换

所以read方法最终返回四个字节,也不会造成文件扩展为原来的四倍;




关键字:     Java基础       IO流       字节流  

备案号:湘ICP备19000029号

Copyright © 2018-2019 javaxl晓码阁 版权所有