commons-compress
概述
处理多种压缩文件格式的 API,包括 ZIP、Tar、Bzip2、Gzip、XZ、Pack200 等。
maven依赖
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.28.0</version></dependency><!-- 解压7z时需要以下依赖 --><dependency><groupId>org.tukaani</groupId><artifactId>xz</artifactId><version>1.9</version></dependency>
示例
创建压缩包并写入文件
ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(new File("E:\\文本.zip"));ZipArchiveEntry entry = new ZipArchiveEntry("a/b/文本.txt");outputStream.putArchiveEntry(entry); //在zip中添加一个文件//直接写入字符串outputStream.write("zip压缩包内文件写入数据".getBytes());//写入文件数据File file = new File("E:\\demo2\\src\\test\\resources\\文本.txt");try (InputStream inputStream = new FileInputStream(file)) {byte[] buffer = new byte[1024 * 5];int length = -1;//每次读取的字节大小。while ((length = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, length);//把数据写入zip中}} catch (FileNotFoundException e) {e.printStackTrace();}outputStream.closeArchiveEntry(); //写入此条目的所有必要数据。如果条目未压缩或压缩后的大小超过4 GB 则抛出异常outputStream.finish();//压缩结束.
解压指定压缩包
ZipArchiveInputStream ais =new ZipArchiveInputStream(new FileInputStream("E:\\文本.zip"));ZipArchiveEntry entry;while (Objects.nonNull(entry = ais.getNextEntry())) {if (!ais.canReadEntryData(entry)) {continue;}File f = new File("E:\\demo2\\src\\test\\resources\\demo\\"+entry.getName());if (entry.isDirectory()) {if (!f.isDirectory() && !f.mkdirs()) {f.mkdirs();}} else {File parent = f.getParentFile();if (!parent.isDirectory() && !parent.mkdirs()) {throw new IOException("failed to create directory " + parent);}try (OutputStream os = Files.newOutputStream(f.toPath())) {byte[] buffer = new byte[1024 * 5];int length = -1;//每次读取的字节大小。while ((length = ais.read(buffer)) != -1) {os.write(buffer, 0, length);//把数据写入zip中}}}
解压7z压缩包
SevenZFile sevenZFile = new SevenZFile(new File("E:\\文本.zip"));SevenZArchiveEntry entry;while ((entry = sevenZFile.getNextEntry()) != null) {// 只解压文件, 跳过文件夹+过滤 MAC 压缩出来的多余文件夹。if (!entry.isDirectory()) {String outFilePath = "E:\\" + entry.getName();File outFile = new File(outFilePath);File parent = outFile.getParentFile();if (!parent.exists()) {parent.mkdirs();}// 获取到当前文件的输入流, 写出到目标文件即可。FileOutputStream os = new FileOutputStream(outFile);try (InputStream ais = sevenZFile.getInputStream(entry)) {byte[] buffer = new byte[1024 * 5];int length = -1;//每次读取的字节大小。while ((length = ais.read(buffer)) != -1) {os.write(buffer, 0, length);//把数据写入zip中}}}}
常用API
可用实现类
输入流 | 输出流 | 条目 | 说明 |
---|---|---|---|
ArArchiveInputStream | ArArchiveOutputStream | ArArchiveEntry | ar解压与压缩 |
ArjArchiveInputStream | ArjArchiveEntry | arj文件解压 | |
CpioArchiveInputStream | CpioArchiveOutputStream | CpioArchiveEntry | cpio解压与压缩 |
DumpArchiveInputStream | DumpArchiveEntry | dump解压 | |
JarArchiveInputStream | JarArchiveOutputStream | JarArchiveEntry | jar解压与压缩 |
TarArchiveInputStream | TarArchiveOutputStream | TarArchiveEntry | tar解压与压缩 |
ZipArchiveInputStream | ZipArchiveOutputStream | ZipArchiveEntry | zip解压与压缩 |
SevenZArchiveEntry | 7z 解压 |
ZipArchiveEntry
方法 | 说明 |
---|---|
ZipArchiveEntry(File inputFile, String entryName) ZipArchiveEntry(Path inputPath, String entryName, LinkOption… options) ZipArchiveEntry(String name) ZipArchiveEntry(ZipArchiveEntry entry) ZipArchiveEntry(ZipEntry entry) | 构造方法。 |
addAsFirstExtraField(ZipExtraField ze) | 添加一个额外的字段 - 替换已经存在的相同类型的额外字段。 |
addExtraField(ZipExtraField ze) | 添加一个额外的字段 - 替换已经存在的相同类型的额外字段。 |
clone() | 克隆对象 |
equals(Object obj) | 判断与指定对象是否相等 |
getCentralDirectoryExtra() | 获取中央目录的额外数据。 |
getLocalFileDataExtra() | 获取本地文件数据的额外数据。 |
getCommentSource() | 获取注释字段值的来源 |
getDataOffset() | 获取存档文件中数据流的偏移量 |
getDiskNumberStart() | 获取此条目开始的拆分段的编号。 |
getInternalAttributes() | 获取内部文件属性。 |
getExternalAttributes() | 获取外部文件属性。 |
getExtraField(ZipShort type) | 通过其标头 ID 获取一个额外的字段。 |
getExtraFields() getExtraFields(boolean includeUnparseable) getExtraFields(ExtraFieldParsingBehavior parsingBehavior) | 获取已成功解析的所有额外字段。 |
getGeneralPurposeBit() | 获取“通用位”字段。 |
getLastModifiedDate() | 获取上次修改日期 |
getLocalHeaderOffset() | 获取本地标头偏移量。 |
getMethod() | 获取此条目的压缩方法,如果未指定压缩方法,则获取 -1。 |
getName() | 获取条目的名称。 |
getNameSource() | name 字段值的源。 |
getPlatform() | 平台规范,放入中央文件头的“版本制作者”部分。 |
getRawFlag() | 标志字段的内容。 |
getRawName() | 返回在使用配置或猜测的编码转换名称之前构成名称的原始字节。 |
getSize() | 获取条目数据的未压缩大小。 |
getTime() | 获取时间 |
getUnixMode() | 获得 Unix 权限。 |
getUnparseableExtraFieldData() | 获取无法正确解析的额外字段数据。 |
getVersionMadeBy() | 获取“版本制作者”字段。 |
getVersionRequired() | 获取“扩展所需的版本”字段。 |
hashCode() | 获取hashCode值。 |
isDirectory() | 判断是否为目录。 |
isStreamContiguous() | 判断流是否连续,即未拆分到多个存档部分、穿插控制块等。 |
isUnixSymlink() | 判断是否表示 Unix 符号链接 |
removeExtraField(ZipShort type) | 删除一个额外的字段。 |
removeUnparseableExtraFieldData() | 删除无法解析的额外字段数据。 |
setAlignment(int alignment) | 设置此条目的对齐方式。 |
setCentralDirectoryExtra(byte[] b) | 设置额外字段的中央目录部分。 |
setCommentSource(CommentSource commentSource) | 设置注释字段值的来源。 |
setCreationTime(FileTime time) | 设置创建时间 |
setDiskNumberStart(long diskNumberStart) | 设置此条目开始的拆分段的编号。 |
setExternalAttributes(long value) | 设置外部文件属性。 |
setExtra(byte[] extra) | 设置额外的数据 |
setExtraFields(ZipExtraField[] fields) | 将所有当前附加的额外字段替换为新数组。 |
setGeneralPurposeBit(GeneralPurposeBit generalPurposeBit) | 设置“通用位”字段。 |
setInternalAttributes(int internalAttributes) | 设置内部文件属性。 |
setLastAccessTime(FileTime fileTime) | 获取最后访问时间 |
setLastModifiedTime(FileTime fileTime) | 获取最后修改时间 |
setMethod(int method) | 设置压缩算法,当前支持ZipEntry.DEFLATED和ZipEntry.STORED两种 |
setNameSource(NameSource nameSource) | 设置名称字段值的来源。 |
setRawFlag(int rawFlag) | 设置标志字段的内容。 |
setSize(long size) | 设置条目数据的未压缩大小。 |
setTime(FileTime fileTime) setTime(long timeEpochMillis) | 设置时间 |
setUnixMode(int mode) | 设置 Unix 权限。 |
setVersionMadeBy(int versionMadeBy) | 设置“版本制作者”字段。 |
setVersionRequired(int versionRequired) | 设置“扩展所需的版本”字段。 |
ZipArchiveOutputStream
方法 | 说明 |
---|---|
ZipArchiveOutputStream(File file) ZipArchiveOutputStream(File file, long zipSplitSize) ZipArchiveOutputStream(OutputStream out) ZipArchiveOutputStream(Path path, long zipSplitSize) ZipArchiveOutputStream(Path file, OpenOption… options) ZipArchiveOutputStream(SeekableByteChannel channel) | 构造方法 |
addRawArchiveEntry(ZipArchiveEntry entry, InputStream rawStream) | 添加一个原始的压缩文件。直接创建文件并写入数据 |
putArchiveEntry(ZipArchiveEntry archiveEntry) | 在zip中创建一个文件 |
createArchiveEntry(File inputFile, String entryName) createArchiveEntry(Path inputPath, String entryName, LinkOption… options) | 创建压缩文件中的条目(如文件或目录) |
canWriteEntryData(ArchiveEntry ae) | 添加可写入的条目 |
close() | 关闭ZipOutputStream |
closeArchiveEntry() | 手动关闭当前条目 |
finish() | 完成7z文件写入后,需要调用finish |
flush() | 刷新流 |
getBytesWritten() | 返回写入此流的总字节数。 |
getEncoding() | 获取编码 |
isSeekable() | 是否正在写入可查找的流 |
setComment(String comment) | 设置压缩文件注释 |
setCreateUnicodeExtraFields(UnicodeExtraFieldPolicy b) | 设置是否创建 Unicode 额外字段。 |
setEncoding(String encoding) | 设置编码,以支持中文等非ASCII字符的文件名 |
setFallbackToUTF8(boolean fallbackToUTF8) | 设置如果无法使用指定的编码对文件名进行编码,则是否回退到 UTF 和语言编码标志。 |
setLevel(int level) | 设置压缩等级 |
setMethod(int method) | 设置压缩算法,当前支持ZipEntry.DEFLATED和ZipEntry.STORED两种 |
setUseLanguageEncodingFlag(boolean b) | 处理 ZIP 文件时用来控制是否使用语言编码标志 |
setUseZip64(Zip64Mode mode) | 是否使用 Zip64 扩展。 |
write(byte[] b, int offset, int length) write(byte b[]) | 写入数据 |
writePreamble(byte[] preamble) writePreamble(byte[] preamble, int offset, int length) | 写入前言数据 |
ZipArchiveInputStream
方法 | 说明 |
---|---|
ZipArchiveInputStream(InputStream inputStream) ZipArchiveInputStream(InputStream inputStream, String encoding) ZipArchiveInputStream(InputStream inputStream, String encoding, boolean useUnicodeExtraFields) ZipArchiveInputStream(InputStream inputStream, String encoding, boolean useUnicodeExtraFields, boolean allowStoredEntriesWithDataDescriptor) ZipArchiveInputStream(InputStream inputStream, String encoding, boolean useUnicodeExtraFields, boolean allowStoredEntriesWithDataDescriptor, boolean skipSplitSig) | 构造方法 useUnicodeExtraFields:使用Unicode额外字段 allowStoredEntriesWithDataDescriptor:允许使用数据描述符存储条目 skipSplitSig:允许你跳过分割文件的签名验证 |
matches(byte[] signature, int length) | 检查签名是否与 ZIP 文件的预期匹配。 |
canReadEntryData(ArchiveEntry ae) | 是否能够读取给定的条目。 |
close() | 关闭流 |
getCompressedCount() | 获取流读取的原始或压缩字节量。 |
getNextEntry() | 获取此流中的下一个存档条目。 |
getUncompressedCount() | 获取未压缩的计数。 |
read(byte[] buffer, int offset, int length) | 读取数据 |
setExtraFieldSupport(Function<ZipShort, ZipExtraField> extraFieldSupport) | 设置自定义额外字段 |
skip(long value) | 跳过并丢弃此输入流中的值字节数据。 |