以下程序是采用多种方式对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;
}
});
}
}