以下程序是採用多種方式對3個文件進行復制
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Date;
import javax.imageio.stream.FileCacheImageInputStream;
import javax.imageio.stream.FileCacheImageOutputStream;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;
public class FileOperate {
public static void main(String[] args) {
// 第一個文件大小10M左右、第二個文件大小100M左右,第三個文件大小爲1000M左右
String[] srcname = new String[] { "F:/文件1", "F:/文件2", "F:/文件3" };
String[] dstname = new String[] { "F:/temp/文件1", "F:/temp/文件2",
"F:/temp/文件3" };
int fsize = 1;
for (int i = 0; i < srcname.length; i++) {
File fsrc = new File(srcname[i]);
if (!fsrc.exists()) {
return;
}
File fdst = new File(dstname[i]);
if (!fdst.exists()) {
try {
fdst.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
}
if (0 < i) {
fsize *= 10;
}
System.out.println("***********幾種複製" + fsize + " M大小文件方式耗時比較*****************");
try {
System.out.print("傳統方式流訪問耗時: ");
System.out.println(forStream(fsrc, fdst) + " ms");
fdst.delete();
fdst.createNewFile();
System.out.print("傳統方式隨機訪問耗時: ");
System.out.println(forRandomAccessFile(fsrc, fdst) + " ms");
fdst.delete();
fdst.createNewFile();
System.out.print("使用影像流讀寫耗時:");
System.out.println(forImageStream(fsrc, fdst) + " ms");
fdst.delete();
fdst.createNewFile();
System.out.print("使用內存影像流讀寫耗時:");
System.out.println(forCacheImageStream(fsrc, fdst) + " ms");
fdst.delete();
fdst.createNewFile();
System.out.print("使用內存緩存影像流讀寫耗時:");
System.out.println(forMemCacheImageStream(fsrc, fdst) + " ms");
fdst.delete();
fdst.createNewFile();
System.out.print("使用NIO中的管道到管道傳輸耗時: ");
System.out.println(forTransfer(fsrc, fdst) + " ms");
fdst.delete();
fdst.createNewFile();
System.out.print("使用NIO管道讀寫耗時:");
System.out.println(forChannel(fsrc, fdst) + " ms");
fdst.delete();
fdst.createNewFile();
System.out.print("使用NIO管道映射讀寫耗時:");
System.out.println(forChannelMap(fsrc, fdst) + " ms");
fdst.delete();
// fdst.createNewFile();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static File delAndNewFile(File file) {
file.deleteOnExit();
File fdst = new File(file.getAbsolutePath());
if (!fdst.exists()) {
try {
fdst.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
return fdst;
}
// 傳統的方式,使用io.FileInputStream、FileOutputStream進行文件讀寫
public static long forStream(File f1, File f2) throws Exception {
long time = new Date().getTime();
FileInputStream in = new FileInputStream(f1);
FileOutputStream out = new FileOutputStream(f2);
int length = 2 * 1024 * 1024; // 此處分配空間的大小影響讀取數據的速度
byte[] buffer = new byte[length];
int readlen = in.read(buffer);
while (-1 != readlen) {
out.write(buffer, 0, readlen);
readlen = in.read(buffer);
}
in.close();
out.flush();
out.close();
return new Date().getTime() - time;
}
// 傳統方式,使用io.RandomAccessFile進行文件讀寫
public static long forRandomAccessFile(File f1, File f2) throws Exception {
long time = new Date().getTime();
RandomAccessFile in = new RandomAccessFile(f1, "r");
RandomAccessFile out = new RandomAccessFile(f2, "rw");
int length = 2 * 1024 * 1024; // 此處分配空間的大小影響讀取數據的速度
byte[] buffer = new byte[length];
int readlen = in.read(buffer);
while (-1 != readlen) {
out.write(buffer, 0, readlen);
readlen = in.read(buffer);
}
in.close();
out.close();
return new Date().getTime() - time;
}
// 使用NIO中的管道到管道傳輸,使用FileChannel,並使用FileChannnel.transferTo進行文件傳輸
public static long forTransfer(File f1, File f2) throws Exception {
long time = new Date().getTime();
FileInputStream in = new FileInputStream(f1);
FileOutputStream out = new FileOutputStream(f2);
FileChannel inC = in.getChannel();
FileChannel outC = out.getChannel();
inC.transferTo(inC.position(), inC.size(), outC);
outC.force(false);
inC.close();
outC.close();
in.close();
out.close();
return new Date().getTime() - time;
}
// 使用NIO中的管道讀寫操作,使用FileChannel,並使用FileChannnel.read和write進行文件讀寫
public static long forChannel(File f1, File f2) throws Exception {
long time = new Date().getTime();
FileInputStream in = new FileInputStream(f1);
FileOutputStream out = new FileOutputStream(f2);
FileChannel inC = in.getChannel();
FileChannel outC = out.getChannel();
ByteBuffer buf = ByteBuffer.allocate(2 * 1024 * 1024); // 此處分配空間的大小影響讀取數據的速度
int readlen = inC.read(buf);
while ((0 != readlen) && (-1 != readlen)) {
buf.flip();
outC.write(buf);
outC.force(false);
buf.clear();
readlen = inC.read(buf);
}
inC.close();
outC.close();
in.close();
out.close();
return new Date().getTime() - time;
}
// 使用NIO中管道Map進行讀寫操作
public static long forChannelMap(File f1, File f2) throws Exception {
long time = new Date().getTime();
FileInputStream in = new FileInputStream(f1);
RandomAccessFile out = new RandomAccessFile(f2, "rw");
FileChannel inC = in.getChannel();
FileChannel outC = out.getChannel();
long fsize = inC.size();
MappedByteBuffer inm = inC.map(MapMode.READ_ONLY, 0, fsize);
int length = 2 * 1024 * 1024; // 此處分配空間的大小影響讀取數據的速度
if (fsize < length) {
length = (int) fsize;
}
MappedByteBuffer readb = inm.load();
int offset = 0;
byte[] buffer = new byte[length];
MappedByteBuffer outm = null;
while (readb.hasRemaining()) {
int remain = readb.remaining();
if (remain < length) {
length = remain;
}
outm = outC.map(MapMode.READ_WRITE, offset, length);
readb.get(buffer, 0, length);
outm.put(buffer, 0, length);
outm.force();
outm.clear();
offset += length;
}
readb.clear();
inm.clear();
//使用MappedByteBuffer進行文件內存映射時,關閉文件channel時無法關閉映射關係,從而導致無法刪除文件直到進程退出。
clean(readb);
clean(inm);
clean(outm);
inC.close();
outC.close();
in.close();
out.close();
return new Date().getTime() - time;
}
// 使用文件FileImageInputStream、FileImageOutputStream
public static long forImageStream(File f1, File f2) throws Exception {
long time = new Date().getTime();
FileImageInputStream inm = new FileImageInputStream(f1);
FileImageOutputStream outm = new FileImageOutputStream(f2);
int length = 2 * 1024 * 1024; // 此處分配空間的大小影響讀取數據的速度
byte[] buffer = new byte[length];
int readlen = inm.read(buffer);
while (-1 != readlen) {
outm.write(buffer, 0, readlen);
readlen = inm.read(buffer);
}
inm.close();
outm.flush();
outm.close();
return new Date().getTime() - time;
}
// 使用文件FileCacheImageInputStream、FileCacheImageOutputStream
public static long forCacheImageStream(File f1, File f2) throws Exception {
long time = new Date().getTime();
File ftmp = new File("F:/temp/");
FileInputStream fim = new FileInputStream(f1);
FileCacheImageInputStream inm = new FileCacheImageInputStream(fim, ftmp);
FileOutputStream fom = new FileOutputStream(f2);
FileCacheImageOutputStream outm = new FileCacheImageOutputStream(fom, ftmp);
int length = 2 * 1024 * 1024; // 此處分配空間的大小影響讀取數據的速度
byte[] buffer = new byte[length];
int readlen = inm.read(buffer);
while (-1 != readlen) {
outm.write(buffer, 0, readlen);
readlen = inm.read(buffer);
}
inm.close();
outm.flush();
outm.close();
fim.close();
fom.close();
return new Date().getTime() - time;
}
// 使用MemoryCacheImageInputStream、MemoryCacheImageOutputStream
public static long forMemCacheImageStream(File f1, File f2) throws Exception {
long time = new Date().getTime();
FileInputStream fim = new FileInputStream(f1);
MemoryCacheImageInputStream inm = new MemoryCacheImageInputStream(fim);
FileOutputStream fom = new FileOutputStream(f2);
MemoryCacheImageOutputStream outm = new MemoryCacheImageOutputStream(fom);
int length = 2 * 1024 * 1024; // 此處分配空間的大小影響讀取數據的速度
byte[] buffer = new byte[length];
inm.reset();
int readlen = inm.read(buffer);
while (-1 != readlen) {
outm.flush();
outm.write(buffer, 0, readlen);
inm.flush();
readlen = inm.read(buffer);
}
inm.close();
fim.close();
outm.flush();
outm.close();
fom.close();
return new Date().getTime() - time;
}
// 傳統的方式,使用io.FileReader、FileWriter進行文件讀寫,注意該方法只能讀取字符文件
public static long forReaderAndWriter(File f1, File f2) throws Exception {
long time = new Date().getTime();
FileReader fread = new FileReader(f1);
FileWriter fwrite = new FileWriter(f2);
int length = 2 * 1024 * 1024; // 此處分配空間的大小影響讀取數據的速度
char[] buffer = new char[length];
int readlen = fread.read(buffer);
while (-1 != readlen) {
fwrite.write(buffer);
readlen = fread.read(buffer);
}
fread.close();
fwrite.flush();
fwrite.close();
return new Date().getTime() - time;
}
/**
* 清理MappedByteBuffer句柄
* @param buffer
*/
public static void clean(final MappedByteBuffer buffer) {
if (buffer == null) {
return;
}
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
Method getCleanerMethod = buffer.getClass().getMethod("cleaner", new Class[0]);
if (getCleanerMethod != null) {
getCleanerMethod.setAccessible(true);
Object cleaner = getCleanerMethod.invoke(buffer, new Object[0]);
Method cleanMethod = cleaner.getClass().getMethod("clean", new Class[0]);
if (cleanMethod != null) {
cleanMethod.invoke(cleaner, new Object[0]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
}
}