大文件的复制,其实就是分段缓存复制的过程。一部分内容缓冲,一部分内容写入。而不是边度边写。边读边写会导致磁盘的磁头反复变换,影响速度。
参考代码如下:
static void copyFile(String sFile, String dFile, int Max_Size) {
int BufferSize = 1024*1024*20;
if (Max_Size != 0) {
BufferSize = Max_Size;
}
File sFile2 = new File(sFile);
File dFile2 = new File(dFile);
if (!sFile2.exists())
return;
if (!dFile2.exists()) {
try {
dFile2.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
}
try {
RandomAccessFile sIn = new RandomAccessFile(sFile2, "r");
try {
RandomAccessFile sOut = new RandomAccessFile(dFile2, "rw");
// 多次读,写
// 根据文件大小来决定
if (BufferSize > sFile2.length()) {
byte[] sByte = new byte[(int) sFile2.length()];
try {
sIn.read(sByte);
} catch (IOException e1) {
// TODO Auto-generated catch block
System.out.print("读源文件错误!\n");
return;
}
try {
sOut.write(sByte);
sOut.close();
sIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.print("文件写入错误!\n");
return;
}
} else {
// System.out.print("Source Size:"+sFile2.length()+"\n");
// System.out.print("(int) (sFile2.length() / BufferSize)"+(int)
// (sFile2.length() / BufferSize)+"\n");
for (int i = 0; i <= (int) (sFile2.length() / BufferSize); i++) {
// System.out.print("第"+i+"段数据\n");
if (i == (int) (sFile2.length() / BufferSize)) {
byte[] sByte = new byte[(int) (sFile2.length() - i
* BufferSize + 1)];
try {
sIn.seek((int) i * BufferSize);
sIn.read(sByte);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.print("读源文件错误!\n");
return;
}
try {
sOut.seek((int) i * BufferSize);
sOut.write(sByte);
sIn.close();
sOut.close();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.print("写入目标文件错误!\n");
return;
}
} else {
byte[] sByte = new byte[BufferSize];
try {
sIn.seek((int) i * BufferSize);
sIn.read(sByte);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.print("读源文件错误!\n");
return;
}
try {
sOut.seek((int) i * BufferSize);
sOut.write(sByte);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.print("写入目标文件错误!\n");
return;
}
}
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
}
在这里面,使用了一个随机文件读写的类: RandomAccessFile
这个类的很多方法与FileInputStream等很相似,有一些有特点的方法,比如seek等。seek用于定位文件指针。