黑马程序员_自定义字节流的缓冲区

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

通过API提供的BufferedInputStream和BufferedOutputStream两个字节流缓冲类,可以提高字节流的高效读取.

一个标准的利用两者的复制操作(拷贝一个acc音频文件)

 

public static void copy() throws IOException
 	{
 		BufferedInputStream buis = new BufferedInputStream(new FileInputStream("g:\\open your mind.aac"));
 		BufferedOutputStream buos = new BufferedOutputStream(new FileOutputStream("g:\\open.acc"));
 		
 		int data = 0;
 		
 		while((data = buis.read()) != -1)
 		{
 			buos.write(data);
 		}
 		
 		buis.close();
 		buos.close();
 	}
 

基本的实现思路是:BufferedInputStream类提供缓冲区技术,将数据读入到缓冲区中,然后用data作为中间件写入到open.acc中.

根据bufferedInputStream原理来实现自定义字节流的缓冲区

 

import java.io.IOException;
import java.io.InputStream;
 
 public class MyBufferedInputStream
 {
 	private InputStream in;
 	private byte[] buf = new byte[1024];
 	private int pos = 0, count = 0;
 
 	public MyBufferedInputStream(InputStream in)
 	{
 		this.in = in;
 	}
 
 	public int myRead() throws IOException
 	{
 		if (count == 0)
 		{
 			count = in.read(buf);
 			if (count < 0)
 				return -1;
 			pos = 0;
 			byte b = buf[pos];
 			count--;
 			pos++;
 			return b & 255;
 		} else if (count > 0)
 		{
 			byte b = buf[pos];
 			count--;
 			pos++;
 			return b & 255;
 		}
 		return -1;
 
 	}
 
 	public void myClose() throws IOException
 	{
 		in.close();
 	}
 }

 

MyEclipse截图分析:

 

 

关于上幅图中的两个问题解答:

 

1.如果直接return b,执行的结果可能是文件复制成功,但是存储容量是小于原文件的.复制是失败的.

2.文件在计算机中的存储都是由二进制数组成的,有可能在数据中出现连续多个1的情况,读一个字节相当于读了8个二进制位,数据中有11111111,转成十进制为-1.

此时-1是byte类型的,而返回的是int类型的,所以byte类型自爱返回时自动被提升为int类型

 

此时由 11111111转换为了11111111 11111111 11111111 11111111转换后仍然是-1.

在执行语句中

 

while((data = buis.read()) != -1)
 		{
 			buos.write(data);
 		}

 

data直接为-1.结束循环,数据没有读取完成,进而write操作没有执行,根本就没有将数据写入到目的中.这就是为啥复制后的文件时小于原文件的.

 

但是为啥利用int类型接收返回的数据,而不是直接用byte呢?

-->为了避免读取数据1111 1111和判断结束标记-1相同的情况,为了保持原有的8个1的基础上,转成int类型的时候,可以再前面补上0而不补1.

-->但是byte类型自动提升为int类型的时候,是直接在前面补上24个1 

 

byte 11111111

int    11111111 11111111 11111111 11111111

结果仍为-1.

 

如果此时在前面补上0,

byte 11111111

int    00000000 00000000 00000000 11111111

此时的结果不为-1,为255.

 

这就是不返回byte类型而返回int类型的原因了

想取最低8位,就与255进行&操作.

将int类型的-1直接与int类型的255进行&操作

  11111111 11111111 11111111 11111111

&00000000 00000000 00000000 11111111

-------------------------------------------------------

  00000000 00000000 00000000 11111111

 

综述:

 

提升到int类型,结果仍为-1,是-1的原因是因为在8个1之前补上的是1,那么补上0,既可以保留原字节数据不变,

又可以避免-1的出现.

 

还有一个问题:

那就是将byte类型提升到int类型后,原来的1个字节,现在变为4个字节.读取时读的是4个字节.写的时候也是4个字节,

那么最后复制的文件的储存容量应该为源文件的4倍.为何复制后到文件大小没有发生变化??

-->此时的操作就是write()方法在执行强转操作,write()方法直接读取最低的字节.

-->read()方法在提升,write()方法在强转...

 

 

Done.

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中,可以使用 `BufferedInputStream` 和 `BufferedOutputStream` 类来扩大字节流缓冲区。这些类提供了一个缓冲区,可以提高读取和写入字节的性能。 要扩大字节流缓冲区,您可以按照以下步骤进行操作: 1. 创建一个 `FileInputStream` 或 `FileOutputStream` 对象,用于读取或写入字节流。例如: ```java FileInputStream fileInputStream = new FileInputStream("input.txt"); FileOutputStream fileOutputStream = new FileOutputStream("output.txt"); ``` 2. 在创建字节输入流或输出流之后,将其传递给 `BufferedInputStream` 或 `BufferedOutputStream` 构造函数。例如: ```java BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); ``` 3. 现在,您可以使用 `bufferedInputStream` 和 `bufferedOutputStream` 对象来读取和写入字节数据。它们会自动处理缓冲区,提高性能。例如: ```java int data; while ((data = bufferedInputStream.read()) != -1) { bufferedOutputStream.write(data); } ``` 4. 最后,确保在使用完毕后关闭流对象,以释放资源。例如: ```java bufferedInputStream.close(); bufferedOutputStream.close(); ``` 通过使用缓冲流,可以提高字节流的读取和写入效率。缓冲区的大小通常是根据系统默认值设定的,但您也可以通过在构造函数中传递缓冲区大小参数来进行自定义。例如: ```java BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 8192); // 自定义缓冲区大小为 8192 字节 ``` 请注意,缓冲区的大小应根据实际需求进行选择,过小的缓冲区可能导致频繁的 I/O 操作,过大的缓冲区则可能占用过多的内存。因此,根据具体情况进行测试和调整是很重要的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值