java多线程解压_如何使用java多线程解压缩大文件夹 – 首选java8?

本文探讨了一种尝试通过多线程来加速解压大型ZIP文件的方法。作者使用Java NIO和固定线程池,将ZIP条目分块处理,但遇到了问题,解压缩过程中只创建了目录而没有文件内容。问题在于如何正确地在多线程环境中处理ZIP输入流。寻求解决方案集中在如何在并发环境下正确读取和解压ZIP块。
摘要由CSDN通过智能技术生成

遭到:

http://www.pixeldonor.com/2013/oct/12/concurrent-zip-compression-java-nio/

我正在尝试解压缩5GB压缩文件,平均需要大约30分钟,这对我们的应用来说很重要,我正在努力减少时间.

我已经尝试了很多组合,改变了缓冲区大小(默认情况下我的写块是4096字节),改变了NIO方法,库,所有结果都差不多.

仍然没有尝试的一件事是按块分割压缩文件,所以通过多线程块读取它.

代码段是:

private static ExecutorService e = Executors.newFixedThreadPool(20);

public static void main(String argv[]) {

try {

String selectedZipFile = "/Users/xx/Documents/test123/large.zip";

String selectedDirectory = "/Users/xx/Documents/test2";

long st = System.currentTimeMillis();

unzip(selectedDirectory, selectedZipFile);

System.out.println(System.currentTimeMillis() - st);

} catch (Exception e) {

e.printStackTrace();

}

}

public static void unzip(String targetDir, String zipFilename) {

ZipInputStream archive;

try {

List list = new ArrayList<>();

archive = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFilename)));

ZipEntry entry;

while ((entry = archive.getNextEntry()) != null) {

list.add(entry);

}

for (List partition : Lists.partition(list, 1000)) {

e.submit(new Multi(targetDir, partition, archive));

}

} catch (Exception e){

e.printStackTrace();

}

}

而runnable是:

static class Multi implements Runnable {

private List partition;

private ZipInputStream zipInputStream;

private String targetDir;

public Multi(String targetDir, List partition, ZipInputStream zipInputStream) {

this.partition = partition;

this.zipInputStream = zipInputStream;

this.targetDir = targetDir;

}

@Override

public void run() {

for (ZipEntry entry : partition) {

File entryDestination = new File(targetDir, entry.getName());

if (entry.isDirectory()) {

entryDestination.mkdirs();

} else {

entryDestination.getParentFile().mkdirs();

BufferedOutputStream output = null;

try {

int n;

byte buf[] = new byte[BUFSIZE];

output = new BufferedOutputStream(new FileOutputStream(entryDestination), BUFSIZE);

while ((n = zipInputStream.read(buf, 0, BUFSIZE)) != -1) {

output.write(buf, 0, n);

}

output.flush();

} catch (FileNotFoundException e1) {

e1.printStackTrace();

} catch (IOException e1) {

e1.printStackTrace();

} finally {

try {

output.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

}

}

}

但由于理由它只存储没有文件内容的目录……

我的问题是:对于上面提到的“压缩”文章的方式,在大型zip文件上制作多线程块的正确方法是什么?

程序测试可用,直接解压导入到工程就可以,bat文件跟shell文件是用于在window跟linux上直接执行的脚本 我把开发的配置文档附上: 1.程序为定时任务,任务执行时间在bin目录下的配置文件mergeFilleUtil.properties中配置,在配置文件中,TASK_PERIOD表示任务执行时间间隔,单位为妙,如一天的时间间隔配置是86400,TASK_BEGIN_HOUR表示任务开始的小时时间,比如9点,TASK_BEGIN_MINUTE表任务开始的分钟,比如30分。 2. 程序用log4j记录日志,日志分正常信息跟错误信息两个级别,日志文件存放在log4j文件夹下。考虑到文件很多,日志解压、移动文件解压、移动1000个记录一次,合并、删除文件每合并、删除50000个记录一次, 3. 启动任务前需配置文件解压合并的路径,本程序需配置的路径如下: 1). PROVINCE_DIR:原始文件存放的路径,必须配置到省的上一级路径,比如存放安徽省的文件路径为E:\test\rootfile\anhui,那么文件的路径必须配置为E:\test\rootfile,否则不能正确显示合并结果; 2). UN_ZIP_PATH:存放解压后的文件的路径; 3). OUT_PATH:存放合并后的文件路径; 4). DONE_FILE_PATH:存放已经解压处理过的文件; 5). DELETE_PATH:配置程序运行结束后欲删除文件的路径,如想删除多个文件夹下的文件,路径之间用逗号隔开,勿加空格,比如:E:\test\rootfile,E:\test\unZip; 4. 注意事项: 本解压合并程序处理文件的逻辑如下: 程序每次解压都去PROVINCE_DIR文件下去解压,将解压后的文件存放到UN_ZIP_PATH下,之后程序启动合并程序合并UN_ZIP_PATH下文件,将合并后的文件按照省份名称存放到OUT_PATH,一个省一个文件。当解压合并结束后,程序将PROVINCE_DIR路径下的文件移动到DONE_FILE_PATH下,并且删除PROVINCE_DIR跟UN_ZIP_PATH下文件,这样保证程序每次运行PROVINCE_DIR文件夹下的文件跟UN_ZIP_PATH下的文件都是最新未处理过的,避免了不断判断文件历史记录所带来的大量时间消耗。 所以为了保证文件解压跟合并的正确性,必须配置好DELETE_PATH路径下的文件,否则合并后的结果是不准确的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值