----------- 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.
分享到:
相关推荐
通过这套《黑马程序员_历经5年锤炼(适合初学者入门的Java基础视频)》,初学者能够系统地学习Java的基础知识,为后续深入学习和实战打下坚实的基础。Java作为一种强大的编程语言,在软件开发领域有着不可替代的地位,...
理解流的分类,如字节流和字符流,以及缓冲区、选择器在NIO中的作用,能够展示对数据传输和资源管理的理解。 4. **多线程**:Java提供了丰富的多线程支持,面试中会考察线程的创建、同步机制(synchronized、Lock)...
- **缓冲区流**:提高读写效率,减少磁盘I/O次数。 - **对象序列化与反序列化**:将对象转换为字节流以便持久化存储或网络传输。 6. **第八章:线程** - **多线程**:允许多个任务同时执行,提高程序并发性。 -...
4. **IO与NIO**:文件操作,字节流和字符流,缓冲流,以及非阻塞I/O模型。 5. **集合框架**:ArrayList、LinkedList、HashSet、HashMap的原理和使用场景。 6. **多线程**:线程的生命周期,线程同步与通信,线程池...
6. **I/O流**:了解输入输出流的基本原理,包括字符流和字节流,以及缓冲流、转换流、对象流和文件操作。 7. **反射**:Java反射机制允许我们在运行时检查类、接口、字段和方法的信息,动态创建对象并调用方法,这...