分别测试各种文件复制的效率:
1.流复制
2.通道复制
3.随机读写复制
4.两个线程并发随机读写复制
测试结果:
文件长度:261736451
407567288:流复制
216968088:通道复制
3507514976:随机读写复制
2140839446:并发随机读写复制
2161234008:并发随机读写复制
结论:文件可以进行并发随机读写,即将一个文件并发分片读出和写入。
尝试使用三线程并发随机读写:
文件长度:261736451
0414495800:流复制
0218568875:通道复制
4337920374:随机读写复制
1889883416:三线程随机读写,
若分成三个线程并发读写,时间方面能够有所缩短。但比通道复制还是相差一个数量级
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; public class RandomAccessFileTest { public static void main(String[] args) throws IOException { // 16,457,539 字节 String filePath = "D:\test\1.zip"; File f = new File(filePath); System.out.println("文件长度:" + f.length()); long beginTime = System.nanoTime(); beginTime = System.nanoTime(); streamCopy(filePath, "D:\test\stream.zip"); System.out.println(System.nanoTime() - beginTime+":流复制"); beginTime = System.nanoTime(); channelCopy(filePath, "D:\test\channel.zip"); System.out.println(System.nanoTime() - beginTime+":通道复制"); beginTime = System.nanoTime(); RandomAccessCopy(filePath, "D:\test\RandomAccess.zip"); System.out.println(System.nanoTime() - beginTime+":随机读写复制"); mutilRandomAccessCopySegment(filePath, "D:\test\mutilRandomAccessCopySegment.zip"); } public static void streamCopy(String sourcePath, String targetPath) throws IOException { File sourceFile = new File(sourcePath); File targetFile = new File(targetPath); InputStream fis = null; OutputStream fos = null; FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; try { fileInputStream = new FileInputStream(sourceFile); fis = new BufferedInputStream(fileInputStream); fileOutputStream = new FileOutputStream(targetFile); fos = new BufferedOutputStream(fileOutputStream); byte[] buf = new byte[1024 * 2]; int len; while ((len = fis.read(buf)) != -1) { fos.write(buf, 0, len); } fos.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { fis.close(); fos.close(); fileInputStream.close(); fileOutputStream.close(); } catch (Exception e) { e.printStackTrace(); } } } public static void channelCopy(String sourcePath, String targetPath) { File sourceFile = new File(sourcePath); File targetFile = new File(targetPath); FileChannel fis = null; FileChannel fos = null; FileInputStream fileInputStream = null; FileOutputStream fileOutputStream = null; try { fileInputStream = new FileInputStream(sourceFile); fis = fileInputStream.getChannel(); fileOutputStream = new FileOutputStream(targetFile); fos = fileOutputStream.getChannel(); fis.transferTo(0, fis.size(), fos); } catch (Exception e) { e.printStackTrace(); } finally { try { fis.close(); fos.close(); fileInputStream.close(); fileOutputStream.close(); } catch (Exception e) { e.printStackTrace(); } } } public static void RandomAccessCopy(String sourcePath, String targetPath) { RandomAccessFile sourceRaf = null; RandomAccessFile targetRaf = null; try { sourceRaf = new RandomAccessFile(sourcePath, "rw"); sourceRaf.seek(0); int len = (int) sourceRaf.length(); byte[] b = new byte[len]; sourceRaf.readFully(b); targetRaf = new RandomAccessFile(targetPath, "rw"); targetRaf.write(b); } catch (IOException e) { e.printStackTrace(); } finally { try { sourceRaf.close(); targetRaf.close(); } catch (Exception e) { e.printStackTrace(); } } } public static void mutilRandomAccessCopySegment(final String sourcePath, final String targetPath) { Thread t1 = new Thread(new Runnable() { public void run() { mutilRandomAccessCopy(sourcePath, targetPath, 0, 87245483); } }); t1.start(); Thread t2 = new Thread(new Runnable() { public void run() { mutilRandomAccessCopy(sourcePath, targetPath, 87245483, 174490966); } }); t2.start(); Thread t3 = new Thread(new Runnable() { public void run() { mutilRandomAccessCopy(sourcePath, targetPath, 174490966, 261736451); } }); t3.start(); } public static void mutilRandomAccessCopy(String sourcePath, String targetPath, int start, int end) { long beginTime = System.nanoTime(); System.out.println("并发读开始时间"+beginTime); RandomAccessFile sourceRaf = null; RandomAccessFile targetRaf = null; int len = end - start; try { sourceRaf = new RandomAccessFile(sourcePath, "rw"); sourceRaf.seek(start); byte[] b = new byte[len]; sourceRaf.readFully(b); targetRaf = new RandomAccessFile(targetPath, "rw"); targetRaf.seek(start); targetRaf.write(b); } catch (IOException e) { e.printStackTrace(); } finally { try { sourceRaf.close(); targetRaf.close(); } catch (Exception e) { e.printStackTrace(); } } System.out.println(System.nanoTime() - beginTime+":并发随机读写复制"); System.out.println("并发读结束时间"+System.nanoTime()); } }