自定义字节缓冲区用于文件复制

来源:互联网 发布:linux什么是管道 编辑:程序博客网 时间:2024/04/28 22:18
/*
 * 刚看完自定义字节缓冲区用于文件复制,自己写一个练练手,把自己U盘里的电影拷贝到电脑里,也算实际应用。
 * 具体实现见代码,在一些容易感到疑惑的地方会有注释。
 */


package filecopy;


import java.io.*;


//自定义字节缓冲区
class MyBufferedInputStream {


private InputStream is;//被装饰的InputStream
private byte[] buf = new byte[1024];//缓冲区
private int pos = 0, count = 0; //定义用于访问缓冲区的指针和计数器

//构造函数,初始化时传入被装饰的字节流对象
public MyBufferedInputStream(InputStream is){
this.is = is;
}

//自定义读方法,底层还是调用字节流对象的read方法
public int myRead(){


byte b; //用于返回读取到的字节
try { //is的read方法会抛出异常
if(count == 0){//如果count等于0,说明缓冲区中无数据需要读取数据到缓冲区
count = is.read(buf);
if(count == -1)//count等于-1,说明数据已经读完,则返回-1
return -1;
pos = 0; //指针清零
}

b = buf[pos]; //记录返回值
pos++; //修改指针和计数器
count--;

//注意此处的返回值,***********************************************************************
//如果只返回b的话会出现文件复制不完全,只会复制一部分。究其原因在于,对于字节文件你可能会碰到8位1的可能,
//即十进制的-1,此时程序会停止运行。为了避免出现这种情况,我们返回结果时将它向上转型为int并与0xff去&运算
//这样会保证返回值的低8位是原来的数据,但不会出现向上转型之后还是-1的情况
//详细讲解请参考其它资料
return b&0xff;


} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("读取文件失败");
e.printStackTrace();
}

return 0;
}

//关闭资源方法
public void myClose(){
try {
if(is != null)
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


public class FileCopy{
public static void main(String[] args){

//定义输入输出流文件
FileInputStream fis = null;
FileOutputStream fos = null;

//用于记录复制文件的时间
long start = System.currentTimeMillis();
long end;
//处理两个流文件可能抛出的异常
try {
fis = new FileInputStream("H:\\新建文件夹\\[电影天堂www.dygod.net].美丽心灵.[中英双字.1024分辨率].rmvb");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("读取文件失败");
e.printStackTrace();
}

try {
fos = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\[电影天堂www.dygod.net].美丽心灵.[中英双字.1024分辨率].rmvb");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("写文件失败");
e.printStackTrace();
}

MyBufferedInputStream mybuf = new MyBufferedInputStream(fis);
BufferedOutputStream buf = new BufferedOutputStream(fos);

int temp;

while((temp = mybuf.myRead()) != -1){
try {
buf.write(temp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

//关闭资源时,考虑异常并处理
mybuf.myClose();
try {
if(buf != null)
buf.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//统计运行时间,  (发现其实并不快,之前感觉可能会快一点)
end = System.currentTimeMillis();

System.out.println(end - start + "毫秒");
}

}
0 0
原创粉丝点击