diff --git a/CHANGELOG.md b/CHANGELOG.md index da5e4695e..00729e860 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/hutool-extra/src/main/java/cn/hutool/extra/compress/CompressUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/compress/CompressUtil.java index 5924ec054..07db936c7 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/compress/CompressUtil.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/compress/CompressUtil.java @@ -3,9 +3,14 @@ package cn.hutool.extra.compress; import cn.hutool.extra.compress.archiver.Archiver; import cn.hutool.extra.compress.archiver.SevenZArchiver; 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.StreamingNotSupportedException; import java.io.File; +import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; @@ -13,8 +18,8 @@ import java.nio.charset.Charset; * 压缩工具类
* 基于commons-compress的压缩解压封装 * - * @since 5.5.0 * @author looly + * @since 5.5.0 */ public class CompressUtil { @@ -54,7 +59,7 @@ public class CompressUtil { * * @param charset 编码 * @param archiverName 归档类型名称,见{@link ArchiveStreamFactory} - * @param out 归档输出的流 + * @param out 归档输出的流 * @return Archiver */ public static Archiver createArchiver(Charset charset, String archiverName, OutputStream out) { @@ -63,4 +68,104 @@ public class CompressUtil { } return StreamArchiver.create(charset, archiverName, out); } + + /** + * 创建归档解包器,支持: + * + * + * @param charset 编码,7z格式此参数无效 + * @param file 归档文件 + * @return {@link Extractor} + */ + public static Extractor createExtractor(Charset charset, File file) { + return createExtractor(charset, null, file); + } + + /** + * 创建归档解包器,支持: + * + * + * @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; + } + } + + /** + * 创建归档解包器,支持: + * + * + * @param charset 编码,7z格式此参数无效 + * @param in 归档输入的流 + * @return {@link Extractor} + */ + public static Extractor createExtractor(Charset charset, InputStream in) { + return createExtractor(charset, null, in); + } + + /** + * 创建归档解包器,支持: + * + * + * @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; + } + } } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/Archiver.java b/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/Archiver.java index e91117296..4211811ff 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/Archiver.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/Archiver.java @@ -1,10 +1,10 @@ package cn.hutool.extra.compress.archiver; +import cn.hutool.core.lang.Filter; import cn.hutool.core.util.StrUtil; import java.io.Closeable; import java.io.File; -import java.io.FileFilter; /** * 数据归档封装,归档即将几个文件或目录打成一个压缩包 @@ -27,10 +27,10 @@ public interface Archiver extends Closeable { * 将文件或目录加入归档,目录采取递归读取方式按照层级加入 * * @param file 文件或目录 - * @param filter 文件过滤器,指定哪些文件或目录可以加入,当{@link FileFilter#accept(File)}为true时加入。 + * @param filter 文件过滤器,指定哪些文件或目录可以加入,当{@link Filter#accept(Object)}为true时加入。 * @return this */ - default Archiver add(File file, FileFilter filter) { + default Archiver add(File file, Filter filter) { return add(file, StrUtil.SLASH, filter); } @@ -39,10 +39,10 @@ public interface Archiver extends Closeable { * * @param file 文件或目录 * @param path 文件或目录的初始路径,null表示位于根路径 - * @param filter 文件过滤器,指定哪些文件或目录可以加入,当{@link FileFilter#accept(File)}为true时加入。 + * @param filter 文件过滤器,指定哪些文件或目录可以加入,当{@link Filter#accept(Object)}为true时加入。 * @return this */ - Archiver add(File file, String path, FileFilter filter); + Archiver add(File file, String path, Filter filter); /** * 结束已经增加的文件归档,此方法不会关闭归档流,可以继续添加文件 diff --git a/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/SevenZArchiver.java b/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/SevenZArchiver.java index 9612defd7..9f371a9c6 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/SevenZArchiver.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/SevenZArchiver.java @@ -3,12 +3,12 @@ package cn.hutool.extra.compress.archiver; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.lang.Filter; import cn.hutool.core.util.StrUtil; import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile; import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; import java.io.File; -import java.io.FileFilter; import java.io.IOException; import java.io.OutputStream; import java.nio.channels.SeekableByteChannel; @@ -67,7 +67,7 @@ public class SevenZArchiver implements Archiver { } @Override - public SevenZArchiver add(File file, String path, FileFilter filter) { + public SevenZArchiver add(File file, String path, Filter filter) { try { addInternal(file, path, filter); } catch (IOException e) { @@ -108,9 +108,9 @@ public class SevenZArchiver implements Archiver { * * @param file 文件或目录 * @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 filter) throws IOException { if (null != filter && false == filter.accept(file)) { return; } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/StreamArchiver.java b/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/StreamArchiver.java index 6c01b8fe0..60eb6a6f0 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/StreamArchiver.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/compress/archiver/StreamArchiver.java @@ -3,6 +3,7 @@ package cn.hutool.extra.compress.archiver; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.lang.Filter; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.compress.CompressException; 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 java.io.File; -import java.io.FileFilter; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; @@ -97,12 +97,12 @@ public class StreamArchiver implements Archiver { * * @param file 文件或目录 * @param path 文件或目录的初始路径,null表示位于根路径 - * @param filter 文件过滤器,指定哪些文件或目录可以加入,当{@link FileFilter#accept(File)}为true时加入。 + * @param filter 文件过滤器,指定哪些文件或目录可以加入,当{@link Filter#accept(Object)}为true时加入。 * @return this * @throws IORuntimeException IO异常 */ @Override - public StreamArchiver add(File file, String path, FileFilter filter) throws IORuntimeException { + public StreamArchiver add(File file, String path, Filter filter) throws IORuntimeException { try { addInternal(file, path, filter); } catch (IOException e) { @@ -141,9 +141,9 @@ public class StreamArchiver implements Archiver { * * @param file 文件或目录 * @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 filter) throws IOException { if (null != filter && false == filter.accept(file)) { return; } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/Extractor.java b/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/Extractor.java index 2ff894107..aa2253674 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/Extractor.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/Extractor.java @@ -1,11 +1,39 @@ 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; + /** - * 数据解包封装,用于将zip、tar等包解包为文件 + * 归档数据解包封装,用于将zip、tar等包解包为文件 * * @author looly * @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 filter); + + /** + * 无异常关闭 + */ + @Override + void close(); } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/SenvenZExtractor.java b/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/SenvenZExtractor.java new file mode 100644 index 000000000..fd6ae48a6 --- /dev/null +++ b/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/SenvenZExtractor.java @@ -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 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 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); + } +} diff --git a/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/Seven7EntryInputStream.java b/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/Seven7EntryInputStream.java new file mode 100644 index 000000000..b3d768cee --- /dev/null +++ b/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/Seven7EntryInputStream.java @@ -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(); + } +} diff --git a/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/StreamExtractor.java b/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/StreamExtractor.java index 338417d34..69e198c5b 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/StreamExtractor.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/compress/extractor/StreamExtractor.java @@ -2,7 +2,10 @@ 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 cn.hutool.core.util.StrUtil; import cn.hutool.extra.compress.CompressException; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveException; @@ -14,29 +17,82 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; -public class StreamExtractor { +/** + * 数据解压器,即将归档打包的数据释放 + * + * @author looly + * @since 5.5.0 + */ +public class StreamExtractor implements Extractor{ 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) { + 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()); try { - this.in = factory.createArchiveInputStream(in); + in = IoUtil.toBuffered(in); + if (StrUtil.isBlank(archiverName)) { + this.in = factory.createArchiveInputStream(in); + } else { + this.in = factory.createArchiveInputStream(archiverName, in); + } } catch (ArchiveException e) { throw new CompressException(e); } } /** - * 释放(解压)到指定目录 + * 释放(解压)到指定目录,结束后自动关闭流,此方法只能调用一次 * * @param targetDir 目标目录 + * @param filter 解压文件过滤器,用于指定需要释放的文件,null表示不过滤。当{@link Filter#accept(Object)}为true时释放。 */ - public void extract(File targetDir) { + @Override + public void extract(File targetDir, Filter filter) { try { - extractInternal(targetDir); + extractInternal(targetDir, filter); } catch (IOException e) { throw new IORuntimeException(e); + } finally { + close(); } } @@ -44,20 +100,21 @@ public class StreamExtractor { * 释放(解压)到指定目录 * * @param targetDir 目标目录 + * @param filter 解压文件过滤器,用于指定需要释放的文件,null表示不过滤。当{@link Filter#accept(Object)}为true时释放。 * @throws IOException IO异常 */ - private void extractInternal(File targetDir) throws IOException { - Assert.isTrue(null != targetDir && targetDir.isDirectory(), "target must be dir."); + private void extractInternal(File targetDir, Filter filter) throws IOException { + Assert.isTrue(null != targetDir && ((false == targetDir.exists()) || targetDir.isDirectory()), "target must be dir."); final ArchiveInputStream in = this.in; ArchiveEntry entry; File outItemFile; - while(null != (entry = this.in.getNextEntry())){ - if(false == in.canReadEntryData(entry)){ + while (null != (entry = in.getNextEntry())) { + if (false == in.canReadEntryData(entry)) { // 无法读取的文件直接跳过 continue; } outItemFile = FileUtil.file(targetDir, entry.getName()); - if(entry.isDirectory()){ + if (entry.isDirectory()) { // 创建对应目录 //noinspection ResultOfMethodCallIgnored outItemFile.mkdirs(); @@ -66,4 +123,9 @@ public class StreamExtractor { } } } + + @Override + public void close() { + IoUtil.close(this.in); + } } diff --git a/hutool-extra/src/test/java/cn/hutool/extra/compress/ArchiverTest.java b/hutool-extra/src/test/java/cn/hutool/extra/compress/ArchiverTest.java index 0b0ee0918..d8ec5e4b7 100644 --- a/hutool-extra/src/test/java/cn/hutool/extra/compress/ArchiverTest.java +++ b/hutool-extra/src/test/java/cn/hutool/extra/compress/ArchiverTest.java @@ -12,6 +12,18 @@ import java.io.File; 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 @Ignore public void tarTest(){ @@ -41,7 +53,7 @@ public class ArchiverTest { public void senvenZTest(){ final File file = FileUtil.file("d:/test/compress/test.7z"); 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()); return true; }) diff --git a/hutool-extra/src/test/java/cn/hutool/extra/compress/ExtractorTest.java b/hutool-extra/src/test/java/cn/hutool/extra/compress/ExtractorTest.java new file mode 100644 index 000000000..ed2a03728 --- /dev/null +++ b/hutool-extra/src/test/java/cn/hutool/extra/compress/ExtractorTest.java @@ -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/")); + } +}