引言
最近在 项目中需要解压带有密码的.7z文件,然后获得里面的数据,之前都是zip 文件没有接触过解压7z类型的 文件,在这分享一下解压工具类,该 工具类可以同时解压带有密码的7z文件和zip文件。
1、pom文件中加入解压需要的三个jar
<dependency> <groupId>net.sf.sevenzipjbinding</groupId> <artifactId>sevenzipjbinding</artifactId> <version>9.20-2.00beta</version> </dependency> <dependency> <groupId>net.sf.sevenzipjbinding</groupId> <artifactId>sevenzipjbinding-all-platforms</artifactId> <version>9.20-2.00beta</version> </dependency> <dependency> <artifactId>commons-io</artifactId> <groupId>commons-io</groupId> <version>2.0.1</version> </dependency>
2、 工具类代码
package com.example.demo.utils; import java.io.File; import java.io.FileOutputStream; import java.io.RandomAccessFile; import java.util.Arrays; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.sf.sevenzipjbinding.ExtractOperationResult; import net.sf.sevenzipjbinding.IInArchive; import net.sf.sevenzipjbinding.ISequentialOutStream; import net.sf.sevenzipjbinding.SevenZip; import net.sf.sevenzipjbinding.SevenZipException; import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream; import net.sf.sevenzipjbinding.simple.ISimpleInArchive; import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem; import org.springframework.stereotype.Service; @Service public class Un7zUtils { private static Logger logger = LoggerFactory.getLogger(Un7zUtils.class); /** * * @Description (解压7z) * @param file7zPath(7z文件路径) * @param outPutPath(解压路径) * @param passWord(文件密码.没有可随便写,或空) * @return * @throws Exception */ public static int un7z(String file7zPath, final String outPutPath, String passWord) throws Exception { IInArchive archive; RandomAccessFile randomAccessFile; randomAccessFile = new RandomAccessFile(file7zPath, "r"); archive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile), passWord); int numberOfItems = archive.getNumberOfItems(); ISimpleInArchive simpleInArchive = archive.getSimpleInterface(); for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) { final int[] hash = new int[] { 0 }; if (!item.isFolder()) { ExtractOperationResult result; final long[] sizeArray = new long[1]; result = item.extractSlow(new ISequentialOutStream() { @Override public int write(byte[] data) throws SevenZipException { try { //String str = item.getPath(); //System.out.println(File.separator); //str = str.substring(0, str.lastIndexOf(File.separator)); //File file = new File(outPutPath + File.separator + str + File.separator); //if (!file.exists()) { // file.mkdirs(); //} File file1 = new File(outPutPath + File.separator + item.getPath()); IOUtils.write(data, new FileOutputStream(file1, true)); } catch (Exception e) { e.printStackTrace(); } hash[0] ^= Arrays.hashCode(data); // Consume data sizeArray[0] += data.length; return data.length; // Return amount of consumed } }, passWord); if (result == ExtractOperationResult.OK) { logger.error("解压成功...." + String.format("%9X | %10s | %s", hash[0], sizeArray[0], item.getPath())); } else { logger.error("解压失败:密码错误或者其他错误...." + result); } } } archive.close(); randomAccessFile.close(); return numberOfItems; } /** * 递归删除文件夹 * * @param file */ public static void deleteFile(File file) { if (file.exists()) { // 判断文件是否存在 if (file.isFile()) { // 判断是否是文件 file.delete(); // 删除文件 } else if (file.isDirectory()) { // 否则如果它是一个目录 File[] files = file.listFiles(); // 声明目录下所有的文件 files[]; for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件 deleteFile(files[i]); // 把每个文件用这个方法进行迭代 } file.delete(); // 删除文件夹 } } } }
3、测试代码
@Test public void un7zip(){ try { un7zUtils.un7z("D:\\7zip\\0320ZC1605查询.zip","D:\\7zip","20190320"); }catch (Exception e){ } }
我在本地 经过测试没有问题,并且我部署到测试服务器也可以正常解压,但是当代码部署到线上 以后遇到问题了,这就很尴尬了,主要怀疑是线上服务器的配置有问题,先看一下错误
java.lang.RuntimeException: SevenZipJBinding couldn't be initialized automaticly using initialization from platform depended JAR and the default temporary directory. Please, make sure the correct 'sevenzipjbinding-<Platform>.jar' file is on the class path or consider initializing SevenZipJBinding manualy using one of the offered initialization methods: 'net.sf.sevenzipjbinding.SevenZip.init*()' Caused by: net.sf.sevenzipjbinding.SevenZipNativeInitializationException: 7-Zip-JBinding initialization failed: Error loading native library: '/var/daihou/datapro/apache-tomcat-8.0.36/temp/SevenZipJBinding-OmKitFPSgs4S/lib7-Zip-JBinding.so' at net.sf.sevenzipjbinding.SevenZip.loadNativeLibraries(SevenZip.java:651) at net.sf.sevenzipjbinding.SevenZip.initSevenZipFromPlatformJARIntern(SevenZip.java:455) at net.sf.sevenzipjbinding.SevenZip.initSevenZipFromPlatformJAR(SevenZip.java:339) at net.sf.sevenzipjbinding.SevenZip.ensureLibraryIsInitialized(SevenZip.java:805) ... 14 more Caused by: java.lang.UnsatisfiedLinkError: /var/daihou/datapro/apache-tomcat-8.0.36/temp/SevenZipJBinding-OmKitFPSgs4S/lib7-Zip-JBinding.so: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by /var/daihou/datapro/apache-tomcat-8.0.36/temp/SevenZipJBinding-OmKitFPSgs4S/lib7-Zip-JBinding.so) at java.lang.ClassLo
从错误信息可以看,该服务器缺少libstdc++.so.6: version `GLIBCXX_3.4.15',我们可以通过下面命令查看一下服务器上是否安装
strings /usr/lib/libstdc++.so.6 | grep GLIBCXX
如果没有这个库,安装一下即可!