java实现 zip rar 7z 压缩包解压

1 篇文章 0 订阅
1 篇文章 0 订阅

1、7z和rar需要引入maven依赖,zip使用java自带的

		<!-- 7z解压依赖 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.9</version>
        </dependency>
        <dependency>
            <groupId>org.tukaani</groupId>
            <artifactId>xz</artifactId>
            <version>1.5</version>
        </dependency>

      	<!-- rar解压依赖 -- >
        <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、编写解压util工具类

/**
 * 文件解压缩工具类
 */	
public class UnFileUtil {

	/**
	 * rar解压缩
	 * @param rarFile	rar文件的全路径
	 * @return  压缩包中所有的文件
	 */	
	@SuppressWarnings("resource")
	public static Map<String, String> unRar(String rarFile) {
		RandomAccessFile randomAccessFile = null;
		IInArchive archive = null;
		try {
			File f = new File(rarFile);
			randomAccessFile = new RandomAccessFile(f.getAbsolutePath(), "rw");
			archive = SevenZip.openInArchive(ArchiveFormat.RAR,
					new RandomAccessFileInStream(randomAccessFile));
			String outPath = f.getAbsolutePath().substring(0, f.getAbsolutePath().indexOf("."));
			File zdir = new File(outPath);
			if (zdir.isDirectory()) {
				zdir.delete();
			}
			zdir.mkdir();

			int[] in = new int[archive.getNumberOfItems()];
			for (int i = 0; i < in.length; i++) {
				in[i] = i;
			}
			archive.extract(in, false, new ExtractCallback(archive,zdir.getAbsolutePath() + "/"));
			//解压后获取压缩包下全部文件列表
			Map<String, String> zipFileMap = getFileNameList(outPath,"");
			return zipFileMap;
		} catch (FileNotFoundException | SevenZipException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(randomAccessFile != null) randomAccessFile.close();
				if(archive != null) archive.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return null;
	}

	/**
	 * 获取压缩包中的全部文件
	 * @param path	文件夹路径
	 * @childName   每一个文件的每一层的路径==D==区分层数
	 * @return  压缩包中所有的文件
	 */	
	private static Map<String, String> getFileNameList(String path, String childName) {
		System.out.println("path:" + path + "---childName:"+childName);
		Map<String, String> files = new HashMap<>();
		File file = new File(path); // 需要获取的文件的路径
		String[] fileNameLists = file.list(); // 存储文件名的String数组
		File[] filePathLists = file.listFiles(); // 存储文件路径的String数组
		for (int i = 0; i < filePathLists.length; i++) {
			if (filePathLists[i].isFile()) {
				files.put(fileNameLists[i] + "==D==" + childName, path + File.separator + filePathLists[i].getName());
			} else {
				files.putAll(getFileNameList(path + File.separator + filePathLists[i].getName(), childName + "&" + filePathLists[i].getName()));
			}
		}
		return files;
	}

	/**
	 * zip解压缩
	 * @param zipFilePath			zip文件的全路径
	 * @param unzipFilePath			解压后文件保存路径
	 * @param includeZipFileName	解压后文件是否包含压缩包文件名,true包含,false不包含
	 * @return 压缩包中所有的文件
	 */
	@SuppressWarnings("resource")
	public static Map<String, String> unZip(String zipFilePath, String unzipFilePath, boolean includeZipFileName) throws Exception{
		File zipFile = new File(zipFilePath);

		//如果包含压缩包文件名,则处理保存路径
		if(includeZipFileName){
			String fileName = zipFile.getName();
			if(StringUtils.isNotEmpty(fileName)){
				fileName = fileName.substring(0,fileName.lastIndexOf("."));
			}
			unzipFilePath = unzipFilePath + File.separator + fileName;
		}

		//判断保存路径是否存在,不存在则创建
		File unzipFileDir = new File(unzipFilePath);
		if(!unzipFileDir.exists() || !unzipFileDir.isDirectory()){
			unzipFileDir.mkdirs();
		}

		//开始解压
		ZipEntry entry = null;
		String entryFilePath = null, entryDirPath = "";
		File entryFile = null, entryDir = null;
		int index = 0, count = 0, bufferSize = 1024;
		byte[] buffer = new byte[bufferSize];
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		Charset gbk = Charset.forName("GBK");
		ZipFile zip = new ZipFile(zipFile, gbk);
		try {
			Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
			while (entries.hasMoreElements()) {
				entry = entries.nextElement();
				entryFilePath = unzipFilePath + File.separator + entry.getName();
				entryFilePath = entryFilePath.replace("/", File.separator);
				index = entryFilePath.lastIndexOf(File.separator);
				if (index != -1) {
					entryDirPath = entryFilePath.substring(0, index);
				}
				entryDir = new File(entryDirPath);
				if (!entryDir.exists() || !entryDir.isDirectory()) {
					entryDir.mkdirs();
				}
				entryFile = new File(entryFilePath);
				//判断当前文件父类路径是否存在,不存在则创建
				if(!entryFile.getParentFile().exists() || !entryFile.getParentFile().isDirectory()){
					entryFile.getParentFile().mkdirs();
				}
				//不是文件说明是文件夹创建即可,无需写入
				if(entryFile.isDirectory()){
					continue;
				}
				bos = new BufferedOutputStream(new FileOutputStream(entryFile));
				bis = new BufferedInputStream(zip.getInputStream(entry));
				while ((count = bis.read(buffer, 0, bufferSize)) != -1) {
					bos.write(buffer, 0, count);
				}
			}
		}catch (Exception e){
			e.printStackTrace();
		}finally {
			bos.flush();
			bos.close();
			bis.close();
			zip.close();
		}
		Map<String, String> resultMap = getFileNameList(unzipFilePath, "");
		return resultMap;
	}

	/**
	 * zip解压缩
	 * @param zipFilePath			zip文件的全路径
	 * @param includeZipFileName	解压后文件是否包含压缩包文件名,true包含,false不包含
	 * @return 压缩包中所有的文件
	 */
	@SuppressWarnings("resource")
	public static Map<String, String> unZip(String zipFilePath, boolean includeZipFileName) throws Exception{
		File zipFile = new File(zipFilePath);
		String unzipFilePath = zipFilePath.substring(0, zipFilePath.lastIndexOf(File.separator));

		//如果包含压缩包文件名,则处理保存路径
		if(includeZipFileName){
			String fileName = zipFile.getName();
			if(StringUtils.isNotEmpty(fileName)){
				fileName = fileName.substring(0,fileName.lastIndexOf("."));
			}
			unzipFilePath = unzipFilePath + File.separator + fileName;
		}

		//判断保存路径是否存在,不存在则创建
		File unzipFileDir = new File(unzipFilePath);
		if(!unzipFileDir.exists() || !unzipFileDir.isDirectory()){
			unzipFileDir.mkdirs();
		}

		//开始解压
		ZipEntry entry = null;
		String entryFilePath = null, entryDirPath = "";
		File entryFile = null, entryDir = null;
		int index = 0, count = 0, bufferSize = 1024;
		byte[] buffer = new byte[bufferSize];
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		Charset gbk = Charset.forName("GBK");
		ZipFile zip = new ZipFile(zipFile, gbk);
		try {
			Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
			while (entries.hasMoreElements()) {
				entry = entries.nextElement();
				entryFilePath = unzipFilePath + File.separator + entry.getName();
				entryFilePath = entryFilePath.replace("/", File.separator);
				index = entryFilePath.lastIndexOf(File.separator);
				if (index != -1) {
					entryDirPath = entryFilePath.substring(0, index);
				}
				entryDir = new File(entryDirPath);
				if (!entryDir.exists() || !entryDir.isDirectory()) {
					entryDir.mkdirs();
				}
				entryFile = new File(entryFilePath);
				//判断当前文件父类路径是否存在,不存在则创建
				if(!entryFile.getParentFile().exists() || !entryFile.getParentFile().isDirectory()){
					entryFile.getParentFile().mkdirs();
				}
				//不是文件说明是文件夹创建即可,无需写入
				if(entryFile.isDirectory()){
					continue;
				}
				bos = new BufferedOutputStream(new FileOutputStream(entryFile));
				bis = new BufferedInputStream(zip.getInputStream(entry));
				while ((count = bis.read(buffer, 0, bufferSize)) != -1) {
					bos.write(buffer, 0, count);
				}
				bos.flush();
				bos.close();
				bis.close();
			}
		}catch (Exception e){
			e.printStackTrace();
		}finally {
			zip.close();
		}
		Map<String, String> resultMap = getFileNameList(unzipFilePath, "");
		return resultMap;
	}

	/**
	 * 7z解压缩
	 * @param z7zFilePath	7z文件的全路径
	 * @return  压缩包中所有的文件
	 */
	public static Map<String, String> un7z(String z7zFilePath){

		String un7zFilePath = "";		//压缩之后的绝对路径

		SevenZFile zIn = null;
		try {
			File file = new File(z7zFilePath);
			un7zFilePath = file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".7z"));
			zIn = new SevenZFile(file);
			SevenZArchiveEntry entry = null;
			File newFile = null;
			while ((entry = zIn.getNextEntry()) != null){
				//不是文件夹就进行解压
				if(!entry.isDirectory()){
					newFile = new File(un7zFilePath, entry.getName());
					if(!newFile.exists()){
						new File(newFile.getParent()).mkdirs();   //创建此文件的上层目录
					}
					OutputStream out = new FileOutputStream(newFile);
					BufferedOutputStream bos = new BufferedOutputStream(out);
					int len = -1;
					byte[] buf = new byte[(int)entry.getSize()];
					while ((len = zIn.read(buf)) != -1){
						bos.write(buf, 0, len);
					}
					bos.flush();
					bos.close();
					out.close();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if (zIn != null)
					zIn.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		Map<String, String> resultMap = getFileNameList(un7zFilePath, "");
		return resultMap;
	}

	public static void main(String[] args) {
		try {
			un7z("C:\\Users\\Admin\\Desktop\\1716F0190017.7z");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在不解压缩的情况下替换zip压缩包中的指定文件,可以使用JavaZipFile和ZipOutputStream类。 首先,使用ZipFile读取原始Zip文件,并且使用ZipOutputStream创建一个新的Zip文件。然后,遍历ZipFile中的所有条目,并将所有条目写入新的ZipOutputStream中,除了要替换的文件。当到达要替换的文件时,使用ZipEntry将文件添加到新的ZipOutputStream中,以便替换原始文件。 以下是一个示例代码: ```java import java.io.*; import java.util.*; import java.util.zip.*; public class ReplaceZipFileEntry { public static void main(String[] args) throws Exception { String zipFileName = "example.zip"; String fileToReplace = "file.txt"; String replacementFileName = "replacement.txt"; // Open the original zip file and create a new one File zipFile = new File(zipFileName); File tempZipFile = new File("temp.zip"); ZipFile zip = new ZipFile(zipFile); ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tempZipFile)); // Loop through all the entries in the original zip file Enumeration entries = zip.entries(); while (entries.hasMoreElements()) { ZipEntry entry = (ZipEntry) entries.nextElement(); // If this is the file to be replaced, add the replacement file instead if (entry.getName().equals(fileToReplace)) { File replacementFile = new File(replacementFileName); FileInputStream fis = new FileInputStream(replacementFile); zos.putNextEntry(new ZipEntry(entry.getName())); byte[] buffer = new byte[1024]; int length; while ((length = fis.read(buffer)) > 0) { zos.write(buffer, 0, length); } fis.close(); } else { // Otherwise, copy the original entry to the new zip file zos.putNextEntry(entry); InputStream is = zip.getInputStream(entry); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { zos.write(buffer, 0, length); } is.close(); } } // Close the streams and delete the original zip file zos.close(); zip.close(); zipFile.delete(); // Rename the temporary zip file to the original name tempZipFile.renameTo(zipFile); } } ``` 在此示例中,我们将替换example.zip文件中名为file.txt的文件。我们使用replacement.txt文件替换它。在代码中,我们首先打开原始zip文件并创建一个新的zip文件(temp.zip)。然后,我们遍历原始zip文件中的所有条目,并将它们添加到新的zip文件中。如果我们到达要替换的文件,我们使用ZipEntry添加replacement.txt文件。最后,我们关闭所有流,删除原始zip文件,并将临时zip文件重命名为原始zip文件的名称。 请注意,这种方法适用于仅替换一个或两个文件的情况。如果您需要替换多个文件,最好解压缩整个zip文件,替换所需的文件,然后重新压缩整个zip文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值