700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > JAVA之ZIP RAR解压工具类

JAVA之ZIP RAR解压工具类

时间:2018-12-16 05:39:14

相关推荐

JAVA之ZIP RAR解压工具类

废话不多说直接上代码

1.相关依赖pom

<dependency><groupId>net.sf.sevenzipjbinding</groupId><artifactId>sevenzipjbinding</artifactId><version>16.02-2.01</version></dependency><dependency><groupId>net.sf.sevenzipjbinding</groupId><artifactId>sevenzipjbinding-all-platforms</artifactId><version>16.02-2.01</version></dependency>

2.解压压缩文件工具类

import net.sf.sevenzipjbinding.IInArchive;import net.sf.sevenzipjbinding.SevenZip;import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.*;import java.nio.charset.Charset;import java.util.Enumeration;import java.util.HashMap;import java.util.List;import java.util.concurrent.atomic.AtomicInteger;import java.util.zip.ZipEntry;import java.util.zip.ZipFile;import java.util.zip.ZipOutputStream;public class UnZipAndRarUtil {private static Logger logger = LoggerFactory.getLogger(UnZipAndRarUtil.class);private static final int BUFFER_SIZE = 2 * 1024;/*** 压缩成ZIP 方法1** @param srcDir 压缩文件夹路径* @param out 压缩文件输出流* @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;*false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)* @throws RuntimeException 压缩失败会抛出运行时异常*/public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) {long start = System.currentTimeMillis();ZipOutputStream zos = null;try {zos = new ZipOutputStream(out);File sourceFile = new File(srcDir);compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);long end = System.currentTimeMillis();logger.debug("压缩完成,耗时:" + (end - start) + " ms");} catch (Exception e) {throw new RuntimeException("zip error from ZipUtils", e);} finally {if (zos != null) {try {zos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 压缩成ZIP 方法2** @param srcFiles 需要压缩的文件列表* @param out压缩文件输出流* @throws RuntimeException 压缩失败会抛出运行时异常*/public static void toZip(List<File> srcFiles, OutputStream out) {long start = System.currentTimeMillis();HashMap<Object, Object> index = new HashMap<>();int count = 0;ZipOutputStream zos = null;try {zos = new ZipOutputStream(out);for (File srcFile : srcFiles) {String fileName = srcFile.getName();logger.debug("压缩文件名称信息:{}", fileName);byte[] buf = new byte[BUFFER_SIZE];//解决文件重名导致压缩失败问题if (index.containsKey(fileName)) {count++;zos.putNextEntry(new ZipEntry("(" + count + ")" + "-" + srcFile.getName()));index.put("(" + count + ")" + "-" + srcFile.getName(), true);} else {zos.putNextEntry(new ZipEntry(srcFile.getName()));index.put(srcFile.getName(), true);}int len;FileInputStream in = new FileInputStream(srcFile);while ((len = in.read(buf)) != -1) {zos.write(buf, 0, len);}zos.closeEntry();in.close();srcFile.delete();}long end = System.currentTimeMillis();logger.info("压缩完成,耗时:" + (end - start) + " ms");} catch (Exception e) {throw new RuntimeException("zip error from ZipUtils", e);} finally {if (zos != null) {try {zos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 递归压缩方法** @param sourceFile 源文件* @param zos zip输出流* @param name 压缩后的名称* @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;*false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)* @throws Exception*/private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) {try {byte[] buf = new byte[BUFFER_SIZE];if (sourceFile.isFile()) {// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字zos.putNextEntry(new ZipEntry(name));// copy文件到zip输出流中int len;FileInputStream in = new FileInputStream(sourceFile);while ((len = in.read(buf)) != -1) {zos.write(buf, 0, len);}zos.closeEntry();in.close();} else {File[] listFiles = sourceFile.listFiles();if (listFiles == null || listFiles.length == 0) {// 需要保留原来的文件结构时,需要对空文件夹进行处理if (KeepDirStructure) {// 空文件夹的处理zos.putNextEntry(new ZipEntry(name + "/"));// 没有文件,不需要文件的copyzos.closeEntry();}} else {for (File file : listFiles) {// 判断是否需要保留原来的文件结构if (KeepDirStructure) {// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了compress(file, zos, name + "/" + file.getName(), KeepDirStructure);} else {compress(file, zos, file.getName(), KeepDirStructure);}}}}} catch (IOException e) {e.printStackTrace();}}/*** <功能描述:> 解压文件到指定目录** @param zipFile zip文件* @param descDir 目标目录* @param levelDepth 解压的最大层级* @return void*/@SuppressWarnings("rawtypes")public static int unPackZip(File zipFile, String descDir, int levelDepth) {int unzipFileNum = 0;try {if (!descDir.endsWith("/")) {descDir = descDir + "/";}File pathFile = new File(descDir);if (!pathFile.exists()) {pathFile.mkdirs();}// 解决zip文件中有中文目录或者中文文件ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {ZipEntry entry = (ZipEntry) entries.nextElement();String zipEntryName = entry.getName();OutputStream out = null;try (InputStream in = zip.getInputStream(entry)) {// 文件名特殊处理String fileEnd = "";if (zipEntryName.contains("/")) {fileEnd = entry.getName().substring(entry.getName().lastIndexOf('/') + 1);} else {fileEnd = entry.getName();}zipEntryName = zipEntryName.substring(0, zipEntryName.lastIndexOf('/') + 1) + fileEnd;String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");// 判断路径是否存在,不存在则创建文件路径File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));if (!file.exists()) {file.mkdirs();}// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压if (new File(outPath).isDirectory()) {continue;}// 获取当前层级int currentLevel = getCurrentLevel(descDir, outPath);if (currentLevel <= levelDepth) {++unzipFileNum;out = new FileOutputStream(outPath);byte[] buf1 = new byte[1024];int len;while ((len = in.read(buf1)) > 0) {out.write(buf1, 0, len);}//输出文件路径信息logger.info(String.format("解压ZIP文件= [%s] 中的文件路径[%s]!", zipFile.getName(), outPath));}} catch (Exception e) {logger.error(String.format("解压ZIP文件= [%s] 中的文件出错!", zipFile.getName()), e);} finally {if (null != out) {out.close();}}}zip.close();logger.info(String.format("解压[%s]文件,共解压出文件=[%s]个文件!", zipFile.getName(), unzipFileNum));} catch (IOException e) {logger.error("解压异常:{}", e);}return unzipFileNum;}private static int getCurrentLevel(String descDir, String outPath) {int currentLevel = 0;String innnerPath = outPath.substring(descDir.length());String[] folderArray = innnerPath.split("/");if (null != folderArray && folderArray.length > 1) {currentLevel = folderArray.length - 1;}return currentLevel;}public static int unRarFiles(File rarFile, String descDir) {if (!descDir.endsWith("/")) {descDir = descDir + "/";}File pathFile = new File(descDir);if (!pathFile.exists()) {pathFile.mkdirs();}try {// 第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFile//r代表以只读的方式打开文本,也就意味着不能用write来操作文件RandomAccessFile randomAccessFile = new RandomAccessFile(rarFile.toString(), "r");// null - autodetectIInArchive archive = SevenZip.openInArchive(null,new RandomAccessFileInStream(randomAccessFile));int[] in = new int[archive.getNumberOfItems()];for (int i = 0; i < in.length; i++) {in[i] = i;}AtomicInteger fileSum = new AtomicInteger(0);archive.extract(in, false, new ExtractCallback(archive, pathFile.getAbsolutePath() + "/"));archive.close();randomAccessFile.close();return fileSum.get();} catch (Exception e) {logger.error("解压rar出错 {}", e.getMessage());}return 0;}// public static void main(String[] args) throws Exception {// String zipFilepath = "D:\\工作内容.zip";// unPackZip(new File(zipFilepath), null, "D:\\data\\fy\\");// }}

3.创建提取文件实现类(IInArchive类属于SevenZip.Archive包)

import net.sf.sevenzipjbinding.*;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.*;public class ExtractCallback implements IArchiveExtractCallback {private static Logger log = LoggerFactory.getLogger(ExtractCallback.class);private int index;private IInArchive inArchive;private String ourDir;public ExtractCallback(IInArchive inArchive, String ourDir) {this.inArchive = inArchive;this.ourDir = ourDir;}@Overridepublic void setCompleted(long arg0) throws SevenZipException {}@Overridepublic void setTotal(long arg0) throws SevenZipException {}@Overridepublic ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {this.index = index;String path = (String) inArchive.getProperty(index, PropID.PATH);final boolean isFolder = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER);String finalPath = path;File newfile = null;try {String fileEnd = "";//对文件名,文件夹特殊处理if (finalPath.contains(File.separator)) {fileEnd = finalPath.substring(finalPath.lastIndexOf(File.separator) + 1);} else {fileEnd = finalPath;}finalPath = finalPath.substring(0, finalPath.lastIndexOf(File.separator) + 1) + fileEnd;//目录层级finalPath = finalPath.replaceAll("\\\\", "/");String suffixName = "";int suffixIndex = fileEnd.lastIndexOf(".");if (suffixIndex != -1) {suffixName = fileEnd.substring(suffixIndex + 1);}newfile = createFile(isFolder, ourDir + finalPath);final boolean directory = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER);} catch (Exception e) {log.error("rar解压失败{}", e.getMessage());}File finalFile = newfile;return data -> {save2File(finalFile, data);return data.length;};}@Overridepublic void prepareOperation(ExtractAskMode arg0) throws SevenZipException {}@Overridepublic void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {}public static File createFile(boolean isFolder, String path) {//前置是因为空文件时不会创建文件和文件夹File file = new File(path);try {if (!isFolder) {File parent = file.getParentFile();if ((!parent.exists())) {parent.mkdirs();}if (!file.exists()) {file.createNewFile();}} else {if ((!file.exists())) {file.mkdirs();}}} catch (Exception e) {log.error("rar创建文件或文件夹失败 {}", e.getMessage());}return file;}public static boolean save2File(File file, byte[] msg) {OutputStream fos = null;try {fos = new FileOutputStream(file, true);fos.write(msg);fos.flush();return true;} catch (FileNotFoundException e) {log.error("rar保存文件失败{}", e.getMessage());return false;} catch (IOException e) {log.error("rar保存文件失败{}", e.getMessage());return false;} finally {try {fos.close();} catch (IOException e) {log.error("rar保存文件失败{}", e.getMessage());}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。