JavaIO-字节缓冲流(BufferedInputStream、BufferedOutputStream)

一)BufferedInputStream输入缓冲流

实现原理:当创建BufferedInputStream时,会创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次有多个字节。 mark操作会记住输入流中的一点,并且reset操作会导致从最近的mark操作之后读取的所有字节在从包含的输入流中取出新的字节之前重新读取。

 

初始化构造方法:

1、BufferedInputStream(InputStream in) 

     创建一个BufferedInputStream并保存其参数,输入流 in,供以后使用。

2、BufferedInputStream(InputStream in, int size) 

     创建一个BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in,供以后使用。 

 

二)BufferedOutputStream输出缓冲流

实现原理:当创建BufferedOutputStream时,会创建一个内部缓冲区数组。应用程序可以向底层输出流写入字节数据,当写入数据时,可以不用每次都去调用底层方法,而是直接从缓存区获取数据。

 

初始化构造方法:

1、BufferedOutputStream(OutputStream out) 

      创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

2、BufferedOutputStream(OutputStream out, int size) 

      创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。 

 

三)BufferedInputStream和BufferedOutputStream使用

方式一:字节输入流和字节输出流实现文件拷贝,一次读取一个字节数据,不建议使用。

/**
 * 方式一:字节输入流和字节输出流实现文件拷贝,一次读取一个字节数据,不建议使用。
 * @throws IOException 
 */
public static void inputAndOutput() {
    long start = System.currentTimeMillis();
		
    BufferedInputStream bufferInput = null;
    BufferedOutputStream bufferOutput = null;
    try {
        // 输入缓冲流
        InputStream input = new FileInputStream(new File("D:\\io\\446MB.rar"));
        bufferInput = new BufferedInputStream(input);
			
        // 输出缓冲流
        OutputStream output = new FileOutputStream(new File("D:\\io\\output_446MB.rar"));
        bufferOutput = new BufferedOutputStream(output);
			
        // 一次读取一个字节
        int len = 0;
        while ((len = bufferInput.read()) != -1) {
        bufferOutput.write(len);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bufferInput != null) {
                bufferInput.close();
            }
            if (bufferOutput != null) {
                bufferOutput.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
		
    long end = System.currentTimeMillis();
    System.out.println("字节输入流和输出流实现文件拷贝,总共耗时" + (end-start) + "ms"); // 446MB文件, 总共耗时大概18秒
}

 

方式二:字节输入流和字节输出流实现文件拷贝,一次读取1024*8个字节数据。

每次只读一个字节数据,会耗时太慢。一次性读一个文件的所有数据,内存可能装不下。分批读写。

/**
 * 方式二:字节输入流和字节输出流实现文件拷贝,一次读取1024*8个字节数据。
 * @throws IOException 
 */
public static void inputAndOutputBytes() {
    long start = System.currentTimeMillis();
		
    BufferedInputStream bufferInput = null;
    BufferedOutputStream bufferOutput = null;
    try {
        // 输入缓冲流
        InputStream input = new FileInputStream(new File("D:\\io\\446MB.rar"));
        bufferInput = new BufferedInputStream(input);
			
        // 输出缓冲流
        OutputStream output = new FileOutputStream(new File("D:\\io\\output_446MB.rar"));
        bufferOutput = new BufferedOutputStream(output);
			
        // 定义个8kb字节数组,作为缓冲区流
        byte[] bytes = new byte[1024*8];
			
        int len = 0;
        while ((len = bufferInput.read(bytes)) != -1) {
            bufferOutput.write(bytes, 0, len);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bufferInput != null) {
                bufferInput.close();
            }
            if (bufferOutput != null) {
                bufferOutput.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
		
    long end = System.currentTimeMillis();
    System.out.println("字节输入流和输出流实现文件拷贝,总共耗时" + (end-start) + "ms"); // 446MB文件, 总共耗时大概1秒
}

 

方式三:字节输入流和字节输出流实现文件拷贝,用http的方式读取远程文件,需借助一个工具类。

/**
 * 方式三:字节输入流和字节输出流实现文件拷贝,用http的方式读取远程文件,需借助一个工具类。
 * @throws IOException 
 */
public static void inputAndOutputHttp() {
    long start = System.currentTimeMillis();
		
    // 远程文件地址
    String requestUrl = "https://localhost:8080/ouyangjun_test/upload/新增广告供应商20190125.rar";
		
    BufferedInputStream bufferInput = null;
    BufferedOutputStream bufferOutput = null;
    try {
        // 获取远程文件InputStream, 跟网速有很大的关系,网速快,读取就快,网速慢,读取就慢
        InputStream input = getHttpInputStream(requestUrl, "GET");
        bufferInput = new BufferedInputStream(input);
			
        OutputStream output = new FileOutputStream(new File("D:\\io\\output_file_test.rar"));
        bufferOutput = new BufferedOutputStream(output);
			
        // 定义个8kb字节数组,作为缓冲区流
        byte[] bytes = new byte[1024*8];
			
        // 一次读取一个字节
        int len = 0;
        while ((len = bufferInput.read(bytes)) != -1) {
            bufferOutput.write(bytes, 0, len);
				
            bufferOutput.flush();
        }
			
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bufferInput != null) {
                bufferInput.close();
            }
            if (bufferOutput != null) {
                bufferOutput.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
		
    long end = System.currentTimeMillis();
    System.out.println("http方式,字节输入流和输出流实现拷贝文件,总共耗时" + (end-start) + "ms"); // 46.8MB的文件,一般网速,总共耗时大概29秒
}

http工具类:

/**
 * http获取远程文件的InputStream
 * @param requestUrl: 请求路径
 * @param requestMethod: 请求方式(GET、POST)
 * @return
 */
public static InputStream getHttpInputStream(String requestUrl, String requestMethod) {
    HttpURLConnection con = null;
    InputStream is = null;
    try {
        URL url = new URL(requestUrl);
			
        // 原生访问http请求,未代理请求
        con = (HttpURLConnection) url.openConnection();
        con.setDoOutput(true);
        con.setDoInput(true);
        con.setUseCaches(false);
        con.setRequestMethod(requestMethod);
        con.setReadTimeout(60000);
        con.setConnectTimeout(60000);
        con.connect();
			
        // 获取InputStream
        is = con.getInputStream();
        return is;
    } catch (IOException e) {
        System.out.println("getHttpInputStream error!" + e);
    }
    return null;
}

 

识别二维码关注个人微信公众号

本章完结,待续,欢迎转载!
 
本文说明:该文章属于原创,如需转载,请标明文章转载来源!

你可能感兴趣的:(JavaIO)