1使用场景
开发过程中可能会用到压缩文件的需求,是用什么方式更快呢?本次就对几种常见的压缩方式做一个对比
2 maven依赖
引用commons-lang3的工具包
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
3 压缩文件工具类
话不多说 直接上代码
import org.apache.commons.lang3.time.StopWatch;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.Pipe;
import java.nio.channels.WritableByteChannel;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class IOStreamTurningExample {
public IOStreamTurningExample() {
}
/**
Native IO Stream
@param srcFile
@param destFile
*/
public static void nativeStreamWriterFile(File srcFile, File destFile) {
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(destFile))) {
try (final FileInputStream fileInputStream = new FileInputStream(srcFile)) {
zipOutputStream.putNextEntry(new ZipEntry(destFile.getName()));
byte[] b = new byte[1024 * 1024 * 5];
int readSize = 0;
while ((readSize = fileInputStream.read(b)) > 0) {
zipOutputStream.write(b, 0, readSize);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
stopWatch.stop();
printInfo("nativeStreamWriterFile", stopWatch);
}
/**
Use Buffer IO Stream
@param srcFile
@param destFile
*/
public static void bufferStreamWriterFile(File srcFile, File destFile) {
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(destFile));
final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(zipOutputStream)) {
try (final BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFile))) {
zipOutputStream.putNextEntry(new ZipEntry(destFile.getName()));
byte[] b = new byte[1024 * 1024 * 5];
int readSize = 0;
while ((readSize = bufferedInputStream.read(b)) != -1) {
bufferedOutputStream.write(b, 0, readSize);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
stopWatch.stop();
printInfo("bufferStreamWriterFile", stopWatch);
}
/**
Use Channel IO Stream
@param srcFile
@param destFile
*/
public static void channelStreamWriterFile(File srcFile, File destFile) {
final long fileSize = srcFile.length();
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(destFile));
final WritableByteChannel writableByteChannel = Channels.newChannel(zipOutputStream)) {
try (final FileChannel fileChannel = new FileInputStream(srcFile).getChannel()) {
zipOutputStream.putNextEntry(new ZipEntry(destFile.getName()));
fileChannel.transferTo(0, fileSize, writableByteChannel);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
stopWatch.stop();
printInfo("channelStreamWriterFile", stopWatch);
}
/**
@param srcFile
@param destFile
*/
public static void mappedStreamWriterFile(File srcFile, File destFile) {
final long fileSize = srcFile.length();
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(destFile));
final WritableByteChannel writableByteChannel = Channels.newChannel(zipOutputStream)) {
zipOutputStream.putNextEntry(new ZipEntry(destFile.getName()));
try (final FileChannel fileChannel = new RandomAccessFile(srcFile, "r").getChannel()) {
final MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileSize);
writableByteChannel.write(mappedByteBuffer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
stopWatch.stop();
printInfo("mappedStreamWriterFile", stopWatch);
}
/**
*
*/
public static void pipeStreamWriterFile(File srcFile, File destFile) {
final long fileSize = srcFile.length();
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destFile));
final WritableByteChannel writableByteChannel = Channels.newChannel(zos)) {
zos.putNextEntry(new ZipEntry(destFile.getName()));
final Pipe pipe = Pipe.open();
CompletableFuture.runAsync(() -> {
try (ZipOutputStream zipOutputStream1 = new ZipOutputStream(Channels.newOutputStream(pipe.sink()));
final WritableByteChannel writableByteChannel1 = Channels.newChannel(zipOutputStream1)) {
zipOutputStream1.putNextEntry(new ZipEntry(destFile.getName()));
final FileChannel destFileChannel = new FileInputStream(srcFile).getChannel();
destFileChannel.transferTo(0, fileSize, writableByteChannel1);
destFileChannel.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
});
final Pipe.SourceChannel sourceChannel = pipe.source();
final ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024 * 10);
while (sourceChannel.read(buffer) >= 0) {
buffer.flip();
writableByteChannel.write(buffer);
buffer.clear();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
stopWatch.stop();
printInfo("pipeStreamWriterFile", stopWatch);
}
private static void printInfo(String method, StopWatch stopWatch) {
System.out.println("\n\n" + method + ":");
System.out.println("Start Time : " + stopWatch.getStartTime());
System.out.println("Duration Time : " + stopWatch.toString());
}
public static void main(String[] args) {
File src_file = new File("D:/test/haha.mp4");
File dest_file = new File("D:/test/haha.mp4");
nativeStreamWriterFile(src_file, dest_file);
bufferStreamWriterFile(src_file, dest_file);
channelStreamWriterFile(src_file, dest_file);
mappedStreamWriterFile(src_file, dest_file);
pipeStreamWriterFile(src_file, dest_file);
try {
TimeUnit.SECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
复制代码修改main方法中的测试文件地址执行并直接执行
4 对比结果查看
haha.mp4是一个1.13G的视频文件
各种方式压缩对比结果:
nativeStreamWriterFile:
Start Time : 1573884268436
Duration Time : 0:00:52.334
bufferStreamWriterFile:
Start Time : 1573884320778
Duration Time : 0:00:51.496
channelStreamWriterFile:
Start Time : 1573884372275
Duration Time : 0:00:52.157
mappedStreamWriterFile:
Start Time : 1573884424432
Duration Time : 0:00:51.618
pipeStreamWriterFile:
Start Time : 1573884476051
Duration Time : 0:01:19.865