java四种文件读写方式及性能比较
Posted braska
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java四种文件读写方式及性能比较相关的知识,希望对你有一定的参考价值。
测试代码
package com.boot.demo.test.io; import java.io.*; import java.lang.reflect.Method; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.security.AccessController; import java.security.PrivilegedAction; /** * @author braska * @date 2020/3/19 **/ public class FileTest { public static void fileStream(String sourceFile, String targetFile) { File file = new File(targetFile); try (FileInputStream fis = new FileInputStream(sourceFile); FileOutputStream fos = new FileOutputStream(file)) { byte[] bytes = new byte[1024 * 1024]; int len; while ((len = fis.read(bytes)) > 0) { fos.write(bytes, 0, len); } } catch (Exception e) { } } public static void bufferStream(String sourceFile, String targetFile) { try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(Paths.get(sourceFile))); BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.get(targetFile), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE))) { byte[] bytes = new byte[1024 * 1024]; int len; while ((len = bis.read(bytes)) > 0) { bos.write(bytes, 0, len); } } catch (Exception e) { e.printStackTrace(); } } public static void randomFile(String sourceFile, String targetFile) { try (RandomAccessFile read = new RandomAccessFile(sourceFile, "r"); RandomAccessFile write = new RandomAccessFile(targetFile, "rw")) { byte[] bytes = new byte[1024 * 1024]; int len; while ((len = read.read(bytes)) > 0) { write.write(bytes, 0, len); } } catch (Exception e) { } } public static void memoryMap(String sourceFile, String targetFile) { try (FileChannel rc = FileChannel.open(Paths.get(sourceFile)); FileChannel wc = FileChannel.open(Paths.get(targetFile), StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)) { long copy = 1L << 30; long cur = 0; long fileLength = rc.size(); while (cur < fileLength) { MappedByteBuffer rMap = rc.map(FileChannel.MapMode.READ_ONLY, cur, copy); MappedByteBuffer wMap = wc.map(FileChannel.MapMode.READ_WRITE, cur, copy); for (int i = 0; i < copy; i++) { byte b = rMap.get(i); //从源文件读取字节 wMap.put(i, b); //把字节写到目标文件中 } System.gc(); //手动调用 GC <必须的,否则出现异常> System.runFinalization(); cur += copy; copy = cur + copy > fileLength ? (fileLength - cur) : copy; } } catch (Exception e) { e.printStackTrace(); } } public static void clean(final MappedByteBuffer buffer) throws Exception { if (buffer == null) { return; } buffer.force(); AccessController.doPrivileged(new PrivilegedAction<Object>() {//Privileged特权 @Override public Object run() { try { // System.out.println(buffer.getClass().getName()); Method getCleanerMethod = buffer.getClass().getMethod("cleaner", new Class[0]); getCleanerMethod.setAccessible(true); sun.misc.Cleaner cleaner = (sun.misc.Cleaner) getCleanerMethod.invoke(buffer, new Object[0]); cleaner.clean(); } catch (Exception e) { e.printStackTrace(); } return null; } }); } private static String buildFilePath(String path, String fileName, String extension) { return String.format("%s%s.%s", path, fileName, extension); } public static void main(String[] args) { /* String path = "F:\workspace\demo\"; String extension = "hprof"; // 30M文件 String sourceFile = buildFilePath(path, "01", extension);*/ /* String path = "E:\software\"; String extension = "exe"; // 460M文件 String sourceFile = buildFilePath(path, "Anaconda3-2019.10-Windows-x86_64", extension);*/ String path = "E:\software\"; String extension = "zip"; // 1.47G文件 String sourceFile = buildFilePath(path, "software", extension); String targetFile; long start; /* targetFile = buildFilePath(path, "target_file_stream", extension); start = System.currentTimeMillis(); FileTest.fileStream(sourceFile, targetFile); System.out.println("file stream used time:" + (System.currentTimeMillis() - start));*/ /* targetFile = buildFilePath(path, "target_buffer_stream", extension); start = System.currentTimeMillis(); FileTest.bufferStream(sourceFile, targetFile); System.out.println("buffer stream used time:" + (System.currentTimeMillis() - start));*/ /* targetFile = buildFilePath(path, "target_random_file", extension); start = System.currentTimeMillis(); FileTest.randomFile(sourceFile, targetFile); System.out.println("random file used time:" + (System.currentTimeMillis() - start));*/ targetFile = buildFilePath(path, "target_memory_map", extension); start = System.currentTimeMillis(); FileTest.memoryMap(sourceFile, targetFile); System.out.println("memory map used time:" + (System.currentTimeMillis() - start)); } }
测试结果
文件大小 | 读写方式 | 耗时 |
---|---|---|
30M | 普通文件流 | 50-60 ms |
缓存流 | 32-35ms | |
随机文件方式 | 40-50ms | |
内存映射文件 | 50-60ms | |
461M | 普通文件流 | 1300-2300 ms |
缓存流 | 1700-2000 ms | |
随机文件方式 | 1300-3000 ms | |
内存映射文件 | 890-1000 ms | |
1.47G | 普通文件流 | 11s |
缓存流 | 9s | |
随机文件方式 | 10s | |
内存映射文件 | 1.6s |
以上是关于java四种文件读写方式及性能比较的主要内容,如果未能解决你的问题,请参考以下文章