Java IO详解(五)------包装流

1.介绍

缓冲流:是一个包装流,目的是缓存作用,加快读取和写入数据的速度。

字节缓冲流:BufferedInputStream、BufferedOutputStream

字符缓冲流:BufferedReader、BufferedWriter

 

以介质是硬盘为例,字节流和字符流的弊端
在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。

为了解决以上弊端,采用缓存流。

缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。

就好比吃饭,不用缓存就是每吃一口都到锅里去铲用缓存就是先把饭盛到碗里,碗里的吃完了,再到锅里去铲缓存流在写入数据的时候,

会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作。

 

2.我们查看 缓冲流的 JDK 底层源码,可以看到,程序中定义了这样的 缓存数组,大小为 8192

BufferedInputStream:

public
class BufferedInputStream extends FilterInputStream {

    private static int DEFAULT_BUFFER_SIZE = 8192;

 

BufferedOutputStream:

public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }

 

3.字节缓冲输入流、字节缓冲输出流

BufferedInputStream、BufferedOutputStream

package stream;

import java.io.*;

/***
 * @ClassName: BufferedInputStreamDem
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/9
 * @version : V1.0
 */
public class BufferedInputStreamDem {

    public static void main(String[] args) throws IOException {
//字节缓冲输入流,创建文件字符流,缓存流必须建立在一个存在的流的基础上 BufferedInputStream bis = new BufferedInputStream( new FileInputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "java.txt")); //定义一个字节数组,用来存储数据 byte[] buffer = new byte[1024]; int len = -1;//定义一个整数,表示读取的字节数 while ((len = bis.read(buffer)) != -1) { System.out.println(new String(buffer, 0, len)); } //关闭流资源 bis.close(); //字节缓冲输出流,创建文件字符流,缓存流必须建立在一个存在的流的基础上 BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "java.txt")); bos.write("ABCD".getBytes()); //关闭流资源 bos.close(); } }

 

4.字符缓冲输入流、字符缓冲输出流

BufferedReader、BufferedWriter

package stream;

import java.io.*;

/***
 * @ClassName: BufferedReaderDemo
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/9
 * @version : V1.0
 */
public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {

        //字符缓冲输入流,创建文件字符流,缓存流必须建立在一个存在的流的基础上
        BufferedReader br = new BufferedReader(
                new FileReader("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "java.txt"));
        char[] buffer = new char[10];
        int len = -1;
        while ((len = br.read(buffer)) != -1) {
            System.out.println(new String(buffer, 0, len));
        }

        //关闭流资源
        br.close();

        //字符缓冲输出流,创建文件字符流,缓存流必须建立在一个存在的流的基础上
        BufferedWriter bw = new BufferedWriter(
                new FileWriter("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "java.txt"));


        bw.write("ABCD");

        //关闭流资源
        bw.close();
    }
}

 

5.转换流:把字节流转换为字符流

InputStreamReader:把字节输入流转换为字符输入流

OutputStreamWriter:把字节输出流转换为字符输出流

用转换流进行文件的复制:

package stream;

import java.io.*;

/***
 * @ClassName: FileOutputStreamCopy
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/10
 * @version : V1.0
 */
public class FileOutputStreamCopy {
    public static void main(String[] args) throws IOException {

        /**
         * 将 a.txt 文件 复制到 b.txt 中
         */
        //1、创建源和目标
        File srcFile = new File("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "a.txt");
        File descFile = new File("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "b.txt");

        //2、创建字节输入输出流对象
        InputStream in = new FileInputStream(srcFile);
        OutputStream out = new FileOutputStream(descFile);

        //3、创建转换输入输出对象
        Reader rd = new InputStreamReader(in);
        Writer wt = new OutputStreamWriter(out);

        //3、读取和写入操作
        char[] buffer = new char[10];//创建一个容量为 10 的字符数组,存储已经读取的数据
        int len = -1;//表示已经读取了多少个字符,如果是 -1,表示已经读取到文件的末尾
        while ((len = rd.read(buffer)) != -1) {
            wt.write(buffer, 0, len);
        }
        //4、关闭流资源
        rd.close();
        wt.close();
    }
}

 

6.内存流(数组流)

把数据先临时存在数组中,也就是内存中。所以关闭 内存流是无效的,关闭后还是可以调用这个类的方法。底层源码的 close()是一个空方法。

 public void close() throws IOException {
    }

 

①、字节内存流:ByteArrayOutputStream 、ByteArrayInputStream

package stream2;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/***
 * @ClassName: ByteArrayDemo
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/10 2:51
 * @version : V1.0
 */
public class ByteArrayDemo {
    public static void main(String[] args) throws IOException {

        //字节数组输出流:程序---》内存
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        //将数据写入到内存中
        bos.write("ABCD".getBytes());

        //创建一个新分配的字节数组。 其大小是此输出流的当前大小,缓冲区的有效内容已被复制到其中。
        byte[] temp = bos.toByteArray();
        System.out.println(new String(temp, 0, temp.length));

        byte[] buffer = new byte[10];

        ///字节数组输入流:内存---》程序
        ByteArrayInputStream bis = new ByteArrayInputStream(temp);

        int len = -1;
        while ((len = bis.read(buffer)) != -1) {
            System.out.println(new String(buffer, 0, len));
        }

        //这里不写也没事,因为源码中的 close()是一个空的方法体
        bos.close();
        bis.close();
    }
}

 

②、字符内存流:CharArrayReader、CharArrayWriter

package stream2;

import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.IOException;

/***
 * @ClassName: CharArrayDemo
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/10
 * @version : V1.0
 */
public class CharArrayDemo {
    public static void main(String[] args) throws IOException {

        //字符数组输出流
        CharArrayWriter caw = new CharArrayWriter();
        caw.write("ABCD");

        //返回内存数据的副本
        char[] temp = caw.toCharArray();
        System.out.println(new String(temp));

        //字符数组输入流
        CharArrayReader car = new CharArrayReader(temp);
        
        char[] buffer = new char[10];
        int len = -1;
        while ((len = car.read(buffer)) != -1) {
            System.out.println(new String(buffer, 0, len));
        }
    }
}

 

③、字符串流:StringReader,StringWriter(把数据临时存储到字符串中)

package stream2;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

/***
 * @ClassName: StringReaderDemo
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/10
 * @version : V1.0
 */
public class StringReaderDemo {
    public static void main(String[] args) throws IOException {

        //字符串输出流,底层采用 StringBuffer 进行拼接
        StringWriter sw = new StringWriter();
        sw.write("ABCD");
        sw.write("帅锅");
        System.out.println(sw.toString());//ABCD帅锅

        //字符串输入流
        StringReader sr = new StringReader(sw.toString());
        
        char[] buffer = new char[10];
        int len = -1;
        while ((len = sr.read(buffer)) != -1) {
            System.out.println(new String(buffer, 0, len));//ABCD帅锅
        }
    }
}

 

6.合并流:把多个输入流合并为一个流,也叫顺序流,因为在读取的时候是先读第一个,读完了在读下面一个流。

package stream2;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.SequenceInputStream;

/***
 * @ClassName: SequenceInputStreamDemo
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/10
 * @version : V1.0
 */
public class SequenceInputStreamDemo {
    public static void main(String[] args) throws IOException {

        //定义字节输入合并流
        SequenceInputStream seinput = new SequenceInputStream(
                new FileInputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "a.txt"),
                new FileInputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "b.txt"));
        byte[] buffer = new byte[10];
        int len = -1;
        while ((len = seinput.read(buffer)) != -1) {
            System.out.println(new String(buffer, 0, len));
        }

        seinput.close();
    }
}

 

参考文章:https://www.cnblogs.com/ysocean/tag/Java%20IO%E8%AF%A6%E8%A7%A3%E7%B3%BB%E5%88%97/

posted @ 2020-06-10 03:04  杵臼  阅读(214)  评论(0编辑  收藏  举报