首先,除了文本文件,其他的像音视频文件还有图片文件要用字节流,
下面是自定义的一个具有缓冲功能的字节输出流
结合这个来分析一下字节流读取字节文件的实现机制吧
public class MyBufferedInputStream {
private InputStream is = null;
private int count = 0 , pos = 0;
private byte[] bytes = new byte[1024];
public MyBufferedInputStream(InputStream is) {
this.is = is;
}
public int read() throws IOException{
int bt = 0;
if(count==0){
count = is.read(bytes);
if(count<0)
return -1;
pos = 0;
}
bt = bytes[pos];
pos++;
count--; //read完成提升操作 write完成截断的强制转型
return bt&255; //与音视频文件二进制编码有关,如果出现连续8个1(即为-1)的字节,则读取该字节自动被提升为int后仍然为 -1 ①
} //则在下面①处就会到导致读写停止,进而造成文件损坏,所以要手动提升让其前面补0而不是1!
public void close() throws IOException{
is.close();
}
public static void main(String[] args) {
MyBufferedInputStream mbis = null;
BufferedOutputStream bos = null;
try {
mbis = new MyBufferedInputStream(new FileInputStream(new File("E:\\你的背包.mp3")));
bos = new BufferedOutputStream(new FileOutputStream(new File("E:\\你的背包"+System.currentTimeMillis()+".mp3")));
int elem = 0;
while ((elem = mbis.read()) != -1) { //①
bos.write(elem);
}
} catch (IOException e) {
throw new RuntimeException("文件读取异常");
}finally{
try {
if (mbis != null)
mbis.close();
} catch (IOException e) {
throw new RuntimeException("输入流关闭异常");
}
try {
if (bos != null)
bos.close();
} catch (IOException e) {
throw new RuntimeException("输出流关闭异常");
}
}
}
}
在这里你解释一下①处的文字的意思,
首先音视频文件和图片文件的底层编码是二进制形式的,我们一般用字节流循环读取数据时都是用while循环判断读取的字节数据是不是为-1,
就像你这句 while ((num=fr.read()) != -1)
但是有一种情况很特殊,如果读取的字节正好8个为全为1,即为11111111,这个字节的值就是-1,而且虽然读取的字节在返回时会自动提升为int型也依然是-1,
所以为了在字节提升时改变这种状况,我们可以让返回结果做下面的运算然后再将得到的结果传到while里进行判断,就是通过下面这种形式
11111111 11111111 11111111 11111111 (这个就是字节型的-1自动提升为int形式的的值,依然为-1)
& 00000000 00000000 00000000 11111111
------------------------------------------------------------------
00000000 00000000 00000000 11111111
这就是上面①处 bt&255的原理,字节流的的曾应该是使用了这种处理机制而字符流没有,字符编码里好像也没有连续8个1的编码情形,这个还有待考证呵呵.....
|