This commit is contained in:
Looly 2020-11-14 03:09:13 +08:00
parent 71ab8335ce
commit e025096896
11 changed files with 454 additions and 30 deletions

View File

@ -3,7 +3,7 @@
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.5.0 (2020-11-11) # 5.5.0 (2020-11-14)
### 新特性 ### 新特性
* 【core 】 NumberUtil.parseInt等支持123,2.00这类数字issue#I23ORQ@Gitee * 【core 】 NumberUtil.parseInt等支持123,2.00这类数字issue#I23ORQ@Gitee

View File

@ -3,9 +3,14 @@ package cn.hutool.extra.compress;
import cn.hutool.extra.compress.archiver.Archiver; import cn.hutool.extra.compress.archiver.Archiver;
import cn.hutool.extra.compress.archiver.SevenZArchiver; import cn.hutool.extra.compress.archiver.SevenZArchiver;
import cn.hutool.extra.compress.archiver.StreamArchiver; import cn.hutool.extra.compress.archiver.StreamArchiver;
import cn.hutool.extra.compress.extractor.Extractor;
import cn.hutool.extra.compress.extractor.SenvenZExtractor;
import cn.hutool.extra.compress.extractor.StreamExtractor;
import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.StreamingNotSupportedException;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -13,8 +18,8 @@ import java.nio.charset.Charset;
* 压缩工具类<br> * 压缩工具类<br>
* 基于commons-compress的压缩解压封装 * 基于commons-compress的压缩解压封装
* *
* @since 5.5.0
* @author looly * @author looly
* @since 5.5.0
*/ */
public class CompressUtil { public class CompressUtil {
@ -63,4 +68,104 @@ public class CompressUtil {
} }
return StreamArchiver.create(charset, archiverName, out); return StreamArchiver.create(charset, archiverName, out);
} }
/**
* 创建归档解包器支持
* <ul>
* <li>{@link ArchiveStreamFactory#AR}</li>
* <li>{@link ArchiveStreamFactory#CPIO}</li>
* <li>{@link ArchiveStreamFactory#JAR}</li>
* <li>{@link ArchiveStreamFactory#TAR}</li>
* <li>{@link ArchiveStreamFactory#ZIP}</li>
* <li>{@link ArchiveStreamFactory#SEVEN_Z}</li>
* </ul>
*
* @param charset 编码7z格式此参数无效
* @param file 归档文件
* @return {@link Extractor}
*/
public static Extractor createExtractor(Charset charset, File file) {
return createExtractor(charset, null, file);
}
/**
* 创建归档解包器支持
* <ul>
* <li>{@link ArchiveStreamFactory#AR}</li>
* <li>{@link ArchiveStreamFactory#CPIO}</li>
* <li>{@link ArchiveStreamFactory#JAR}</li>
* <li>{@link ArchiveStreamFactory#TAR}</li>
* <li>{@link ArchiveStreamFactory#ZIP}</li>
* <li>{@link ArchiveStreamFactory#SEVEN_Z}</li>
* </ul>
*
* @param charset 编码7z格式此参数无效
* @param archiverName 归档类型名称{@link ArchiveStreamFactory}null表示自动识别
* @param file 归档文件
* @return {@link Extractor}
*/
public static Extractor createExtractor(Charset charset, String archiverName, File file) {
if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(archiverName)) {
return new SenvenZExtractor(file);
}
try{
return new StreamExtractor(charset, archiverName, file);
} catch (CompressException e){
final Throwable cause = e.getCause();
if(cause instanceof StreamingNotSupportedException && cause.getMessage().contains("7z")){
return new SenvenZExtractor(file);
}
throw e;
}
}
/**
* 创建归档解包器支持
* <ul>
* <li>{@link ArchiveStreamFactory#AR}</li>
* <li>{@link ArchiveStreamFactory#CPIO}</li>
* <li>{@link ArchiveStreamFactory#JAR}</li>
* <li>{@link ArchiveStreamFactory#TAR}</li>
* <li>{@link ArchiveStreamFactory#ZIP}</li>
* <li>{@link ArchiveStreamFactory#SEVEN_Z}</li>
* </ul>
*
* @param charset 编码7z格式此参数无效
* @param in 归档输入的流
* @return {@link Extractor}
*/
public static Extractor createExtractor(Charset charset, InputStream in) {
return createExtractor(charset, null, in);
}
/**
* 创建归档解包器支持
* <ul>
* <li>{@link ArchiveStreamFactory#AR}</li>
* <li>{@link ArchiveStreamFactory#CPIO}</li>
* <li>{@link ArchiveStreamFactory#JAR}</li>
* <li>{@link ArchiveStreamFactory#TAR}</li>
* <li>{@link ArchiveStreamFactory#ZIP}</li>
* <li>{@link ArchiveStreamFactory#SEVEN_Z}</li>
* </ul>
*
* @param charset 编码7z格式此参数无效
* @param archiverName 归档类型名称{@link ArchiveStreamFactory}null表示自动识别
* @param in 归档输入的流
* @return {@link Extractor}
*/
public static Extractor createExtractor(Charset charset, String archiverName, InputStream in) {
if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(archiverName)) {
return new SenvenZExtractor(in);
}
try{
return new StreamExtractor(charset, archiverName, in);
} catch (CompressException e){
final Throwable cause = e.getCause();
if(cause instanceof StreamingNotSupportedException && cause.getMessage().contains("7z")){
return new SenvenZExtractor(in);
}
throw e;
}
}
} }

View File

@ -1,10 +1,10 @@
package cn.hutool.extra.compress.archiver; package cn.hutool.extra.compress.archiver;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import java.io.Closeable; import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.FileFilter;
/** /**
* 数据归档封装归档即将几个文件或目录打成一个压缩包 * 数据归档封装归档即将几个文件或目录打成一个压缩包
@ -27,10 +27,10 @@ public interface Archiver extends Closeable {
* 将文件或目录加入归档目录采取递归读取方式按照层级加入 * 将文件或目录加入归档目录采取递归读取方式按照层级加入
* *
* @param file 文件或目录 * @param file 文件或目录
* @param filter 文件过滤器指定哪些文件或目录可以加入{@link FileFilter#accept(File)}为true时加入 * @param filter 文件过滤器指定哪些文件或目录可以加入{@link Filter#accept(Object)}为true时加入
* @return this * @return this
*/ */
default Archiver add(File file, FileFilter filter) { default Archiver add(File file, Filter<File> filter) {
return add(file, StrUtil.SLASH, filter); return add(file, StrUtil.SLASH, filter);
} }
@ -39,10 +39,10 @@ public interface Archiver extends Closeable {
* *
* @param file 文件或目录 * @param file 文件或目录
* @param path 文件或目录的初始路径null表示位于根路径 * @param path 文件或目录的初始路径null表示位于根路径
* @param filter 文件过滤器指定哪些文件或目录可以加入{@link FileFilter#accept(File)}为true时加入 * @param filter 文件过滤器指定哪些文件或目录可以加入{@link Filter#accept(Object)}为true时加入
* @return this * @return this
*/ */
Archiver add(File file, String path, FileFilter filter); Archiver add(File file, String path, Filter<File> filter);
/** /**
* 结束已经增加的文件归档此方法不会关闭归档流可以继续添加文件 * 结束已经增加的文件归档此方法不会关闭归档流可以继续添加文件

View File

@ -3,12 +3,12 @@ package cn.hutool.extra.compress.archiver;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile; import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;
import java.io.File; import java.io.File;
import java.io.FileFilter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.channels.SeekableByteChannel; import java.nio.channels.SeekableByteChannel;
@ -67,7 +67,7 @@ public class SevenZArchiver implements Archiver {
} }
@Override @Override
public SevenZArchiver add(File file, String path, FileFilter filter) { public SevenZArchiver add(File file, String path, Filter<File> filter) {
try { try {
addInternal(file, path, filter); addInternal(file, path, filter);
} catch (IOException e) { } catch (IOException e) {
@ -108,9 +108,9 @@ public class SevenZArchiver implements Archiver {
* *
* @param file 文件或目录 * @param file 文件或目录
* @param path 文件或目录的初始路径null表示位于根路径 * @param path 文件或目录的初始路径null表示位于根路径
* @param filter 文件过滤器指定哪些文件或目录可以加入{@link FileFilter#accept(File)}为true时加入 * @param filter 文件过滤器指定哪些文件或目录可以加入{@link Filter#accept(Object)}为true时加入
*/ */
private void addInternal(File file, String path, FileFilter filter) throws IOException { private void addInternal(File file, String path, Filter<File> filter) throws IOException {
if (null != filter && false == filter.accept(file)) { if (null != filter && false == filter.accept(file)) {
return; return;
} }

View File

@ -3,6 +3,7 @@ package cn.hutool.extra.compress.archiver;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.compress.CompressException; import cn.hutool.extra.compress.CompressException;
import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveException;
@ -12,7 +13,6 @@ import org.apache.commons.compress.archivers.ar.ArArchiveOutputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import java.io.File; import java.io.File;
import java.io.FileFilter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -97,12 +97,12 @@ public class StreamArchiver implements Archiver {
* *
* @param file 文件或目录 * @param file 文件或目录
* @param path 文件或目录的初始路径null表示位于根路径 * @param path 文件或目录的初始路径null表示位于根路径
* @param filter 文件过滤器指定哪些文件或目录可以加入{@link FileFilter#accept(File)}为true时加入 * @param filter 文件过滤器指定哪些文件或目录可以加入{@link Filter#accept(Object)}为true时加入
* @return this * @return this
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
*/ */
@Override @Override
public StreamArchiver add(File file, String path, FileFilter filter) throws IORuntimeException { public StreamArchiver add(File file, String path, Filter<File> filter) throws IORuntimeException {
try { try {
addInternal(file, path, filter); addInternal(file, path, filter);
} catch (IOException e) { } catch (IOException e) {
@ -141,9 +141,9 @@ public class StreamArchiver implements Archiver {
* *
* @param file 文件或目录 * @param file 文件或目录
* @param path 文件或目录的初始路径null表示位于根路径 * @param path 文件或目录的初始路径null表示位于根路径
* @param filter 文件过滤器指定哪些文件或目录可以加入{@link FileFilter#accept(File)}为true时加入 * @param filter 文件过滤器指定哪些文件或目录可以加入{@link Filter#accept(Object)}为true时加入
*/ */
private void addInternal(File file, String path, FileFilter filter) throws IOException { private void addInternal(File file, String path, Filter<File> filter) throws IOException {
if (null != filter && false == filter.accept(file)) { if (null != filter && false == filter.accept(file)) {
return; return;
} }

View File

@ -1,11 +1,39 @@
package cn.hutool.extra.compress.extractor; package cn.hutool.extra.compress.extractor;
import cn.hutool.core.lang.Filter;
import org.apache.commons.compress.archivers.ArchiveEntry;
import java.io.Closeable;
import java.io.File;
/** /**
* 数据解包封装用于将ziptar等包解包为文件 * 归档数据解包封装用于将ziptar等包解包为文件
* *
* @author looly * @author looly
* @since 5.5.0 * @since 5.5.0
*/ */
public interface Extractor { public interface Extractor extends Closeable {
/**
* 释放解压到指定目录结束后自动关闭流此方法只能调用一次
*
* @param targetDir 目标目录
*/
default void extract(File targetDir){
extract(targetDir, null);
}
/**
* 释放解压到指定目录结束后自动关闭流此方法只能调用一次
*
* @param targetDir 目标目录
* @param filter 解压文件过滤器用于指定需要释放的文件null表示不过滤{@link Filter#accept(Object)}为true时释放
*/
void extract(File targetDir, Filter<ArchiveEntry> filter);
/**
* 无异常关闭
*/
@Override
void close();
} }

View File

@ -0,0 +1,142 @@
package cn.hutool.extra.compress.extractor;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Filter;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.SeekableByteChannel;
/**
* 7z格式数据解压器即将归档打包的数据释放
*
* @author looly
* @since 5.5.0
*/
public class SenvenZExtractor implements Extractor {
private final SevenZFile sevenZFile;
/**
* 构造
*
* @param file 包文件
*/
public SenvenZExtractor(File file) {
this(file, null);
}
/**
* 构造
*
* @param file 包文件
* @param password 密码null表示无密码
*/
public SenvenZExtractor(File file, char[] password) {
try {
this.sevenZFile = new SevenZFile(file, password);
} catch (IOException e) {
throw new IORuntimeException(e);
}
}
/**
* 构造
*
* @param in 包流
*/
public SenvenZExtractor(InputStream in) {
this(in, null);
}
/**
* 构造
*
* @param in 包流
* @param password 密码null表示无密码
*/
public SenvenZExtractor(InputStream in, char[] password) {
this(new SeekableInMemoryByteChannel(IoUtil.readBytes(in)), password);
}
/**
* 构造
*
* @param channel {@link SeekableByteChannel}
*/
public SenvenZExtractor(SeekableByteChannel channel) {
this(channel, null);
}
/**
* 构造
*
* @param channel {@link SeekableByteChannel}
* @param password 密码null表示无密码
*/
public SenvenZExtractor(SeekableByteChannel channel, char[] password) {
try {
this.sevenZFile = new SevenZFile(channel, password);
} catch (IOException e) {
throw new IORuntimeException(e);
}
}
/**
* 释放解压到指定目录结束后自动关闭流此方法只能调用一次
*
* @param targetDir 目标目录
* @param filter 解压文件过滤器用于指定需要释放的文件null表示不过滤{@link Filter#accept(Object)}为true时释放
*/
@Override
public void extract(File targetDir, Filter<ArchiveEntry> filter) {
try {
extractInternal(targetDir, filter);
} catch (IOException e) {
throw new IORuntimeException(e);
} finally {
close();
}
}
/**
* 释放解压到指定目录
*
* @param targetDir 目标目录
* @param filter 解压文件过滤器用于指定需要释放的文件null表示不过滤{@link Filter#accept(Object)}为true时释放
* @throws IOException IO异常
*/
private void extractInternal(File targetDir, Filter<ArchiveEntry> filter) throws IOException {
Assert.isTrue(null != targetDir && ((false == targetDir.exists()) || targetDir.isDirectory()), "target must be dir.");
final SevenZFile sevenZFile = this.sevenZFile;
SevenZArchiveEntry entry;
File outItemFile;
while (null != (entry = this.sevenZFile.getNextEntry())) {
outItemFile = FileUtil.file(targetDir, entry.getName());
if (entry.isDirectory()) {
// 创建对应目录
//noinspection ResultOfMethodCallIgnored
outItemFile.mkdirs();
} else if(entry.hasStream()){
// 读取entry对应数据流
FileUtil.writeFromStream(new Seven7EntryInputStream(sevenZFile, entry), outItemFile);
} else {
// 无数据流的文件创建为空文件
FileUtil.touch(outItemFile);
}
}
}
@Override
public void close() {
IoUtil.close(this.sevenZFile);
}
}

View File

@ -0,0 +1,45 @@
package cn.hutool.extra.compress.extractor;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import java.io.IOException;
import java.io.InputStream;
/**
* 7z解压中文件流读取的封装
*
* @author looly
* @since 5.5.0
*/
public class Seven7EntryInputStream extends InputStream {
private final SevenZFile sevenZFile;
private final long size;
private long readSize = 0;
/**
* 构造
* @param sevenZFile {@link SevenZFile}
* @param entry {@link SevenZArchiveEntry}
*/
public Seven7EntryInputStream(SevenZFile sevenZFile, SevenZArchiveEntry entry) {
this.sevenZFile = sevenZFile;
this.size = entry.getSize();
}
@Override
public int available() throws IOException {
try{
return Math.toIntExact(this.size);
} catch (ArithmeticException e){
throw new IOException("Entry size is too large!(max than Integer.MAX)", e);
}
}
@Override
public int read() throws IOException {
this.readSize++;
return this.sevenZFile.read();
}
}

View File

@ -2,7 +2,10 @@ package cn.hutool.extra.compress.extractor;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.compress.CompressException; import cn.hutool.extra.compress.CompressException;
import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveException;
@ -14,29 +17,82 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
public class StreamExtractor { /**
* 数据解压器即将归档打包的数据释放
*
* @author looly
* @since 5.5.0
*/
public class StreamExtractor implements Extractor{
private final ArchiveInputStream in; private final ArchiveInputStream in;
/**
* 构造
*
* @param charset 编码
* @param file 包文件
*/
public StreamExtractor(Charset charset, File file) {
this(charset, null, file);
}
/**
* 构造
*
* @param charset 编码
* @param archiverName 归档包格式null表示自动检测
* @param file 包文件
*/
public StreamExtractor(Charset charset, String archiverName, File file) {
this(charset, archiverName, FileUtil.getInputStream(file));
}
/**
* 构造
*
* @param charset 编码
* @param in 包流
*/
public StreamExtractor(Charset charset, InputStream in) { public StreamExtractor(Charset charset, InputStream in) {
this(charset, null, in);
}
/**
* 构造
*
* @param charset 编码
* @param archiverName 归档包格式null表示自动检测
* @param in 包流
*/
public StreamExtractor(Charset charset, String archiverName, InputStream in) {
final ArchiveStreamFactory factory = new ArchiveStreamFactory(charset.name()); final ArchiveStreamFactory factory = new ArchiveStreamFactory(charset.name());
try { try {
in = IoUtil.toBuffered(in);
if (StrUtil.isBlank(archiverName)) {
this.in = factory.createArchiveInputStream(in); this.in = factory.createArchiveInputStream(in);
} else {
this.in = factory.createArchiveInputStream(archiverName, in);
}
} catch (ArchiveException e) { } catch (ArchiveException e) {
throw new CompressException(e); throw new CompressException(e);
} }
} }
/** /**
* 释放解压到指定目录 * 释放解压到指定目录结束后自动关闭流此方法只能调用一次
* *
* @param targetDir 目标目录 * @param targetDir 目标目录
* @param filter 解压文件过滤器用于指定需要释放的文件null表示不过滤{@link Filter#accept(Object)}为true时释放
*/ */
public void extract(File targetDir) { @Override
public void extract(File targetDir, Filter<ArchiveEntry> filter) {
try { try {
extractInternal(targetDir); extractInternal(targetDir, filter);
} catch (IOException e) { } catch (IOException e) {
throw new IORuntimeException(e); throw new IORuntimeException(e);
} finally {
close();
} }
} }
@ -44,20 +100,21 @@ public class StreamExtractor {
* 释放解压到指定目录 * 释放解压到指定目录
* *
* @param targetDir 目标目录 * @param targetDir 目标目录
* @param filter 解压文件过滤器用于指定需要释放的文件null表示不过滤{@link Filter#accept(Object)}为true时释放
* @throws IOException IO异常 * @throws IOException IO异常
*/ */
private void extractInternal(File targetDir) throws IOException { private void extractInternal(File targetDir, Filter<ArchiveEntry> filter) throws IOException {
Assert.isTrue(null != targetDir && targetDir.isDirectory(), "target must be dir."); Assert.isTrue(null != targetDir && ((false == targetDir.exists()) || targetDir.isDirectory()), "target must be dir.");
final ArchiveInputStream in = this.in; final ArchiveInputStream in = this.in;
ArchiveEntry entry; ArchiveEntry entry;
File outItemFile; File outItemFile;
while(null != (entry = this.in.getNextEntry())){ while (null != (entry = in.getNextEntry())) {
if(false == in.canReadEntryData(entry)){ if (false == in.canReadEntryData(entry)) {
// 无法读取的文件直接跳过 // 无法读取的文件直接跳过
continue; continue;
} }
outItemFile = FileUtil.file(targetDir, entry.getName()); outItemFile = FileUtil.file(targetDir, entry.getName());
if(entry.isDirectory()){ if (entry.isDirectory()) {
// 创建对应目录 // 创建对应目录
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
outItemFile.mkdirs(); outItemFile.mkdirs();
@ -66,4 +123,9 @@ public class StreamExtractor {
} }
} }
} }
@Override
public void close() {
IoUtil.close(this.in);
}
} }

View File

@ -12,6 +12,18 @@ import java.io.File;
public class ArchiverTest { public class ArchiverTest {
@Test
@Ignore
public void zipTest(){
final File file = FileUtil.file("d:/test/compress/test.zip");
StreamArchiver.create(CharsetUtil.CHARSET_UTF_8, ArchiveStreamFactory.ZIP, file)
.add(FileUtil.file("d:/Java"), (f)->{
Console.log("Add: {}", f.getPath());
return true;
})
.finish().close();
}
@Test @Test
@Ignore @Ignore
public void tarTest(){ public void tarTest(){
@ -41,7 +53,7 @@ public class ArchiverTest {
public void senvenZTest(){ public void senvenZTest(){
final File file = FileUtil.file("d:/test/compress/test.7z"); final File file = FileUtil.file("d:/test/compress/test.7z");
CompressUtil.createArchiver(CharsetUtil.CHARSET_UTF_8, ArchiveStreamFactory.SEVEN_Z, file) CompressUtil.createArchiver(CharsetUtil.CHARSET_UTF_8, ArchiveStreamFactory.SEVEN_Z, file)
.add(FileUtil.file("d:/Java"), (f)->{ .add(FileUtil.file("d:/Java/apache-maven-3.6.3"), (f)->{
Console.log("Add: {}", f.getPath()); Console.log("Add: {}", f.getPath());
return true; return true;
}) })

View File

@ -0,0 +1,30 @@
package cn.hutool.extra.compress;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.extra.compress.extractor.Extractor;
import org.junit.Ignore;
import org.junit.Test;
public class ExtractorTest {
@Test
// @Ignore
public void zipTest(){
Extractor extractor = CompressUtil.createExtractor(
CharsetUtil.defaultCharset(),
FileUtil.file("d:/test/compress/test.zip"));
extractor.extract(FileUtil.file("d:/test/compress/test2/"));
}
@Test
@Ignore
public void sevenZTest(){
Extractor extractor = CompressUtil.createExtractor(
CharsetUtil.defaultCharset(),
FileUtil.file("d:/test/compress/test.7z"));
extractor.extract(FileUtil.file("d:/test/compress/test2/"));
}
}