电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

Java 如何實(shí)現(xiàn)解壓縮文件和文件夾

瀏覽:83日期:2022-08-15 14:40:28
一 前言

項(xiàng)目開發(fā)中,總會遇到解壓縮文件的時候。比如,用戶下載多個文件時,服務(wù)端可以將多個文件壓縮成一個文件(例如xx.zip或xx.rar)。用戶上傳資料時,允許上傳壓縮文件,服務(wù)端進(jìn)行解壓讀取每一個文件。

基于通用性,以下介紹幾種解壓縮文件的方式,包裝成工具類,供平時開發(fā)使用。

二 壓縮文件

壓縮文件,顧名思義,即把一個或多個文件壓縮成一個文件。壓縮也有2種形式,一種是將所有文件壓縮到同一目錄下,此種方式要注意文件重名覆蓋的問題。另一種是按原有文件樹結(jié)構(gòu)進(jìn)行壓縮,即壓縮后的文件樹結(jié)構(gòu)保持不變。

壓縮文件操作,會使用到一個類,即ZipOutputStream。

2.1 壓縮多個文件

此方法將所有文件壓縮到同一個目錄下。方法傳入多個文件列表,和一個最終壓縮到的文件路徑名。

/** * 壓縮多個文件,壓縮后的所有文件在同一目錄下 * * @param zipFileName 壓縮后的文件名 * @param files 需要壓縮的文件列表 * @throws IOException IO異常 */ public static void zipMultipleFiles(String zipFileName, File... files) throws IOException { ZipOutputStream zipOutputStream = null; try { // 輸出流 zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName)); // 遍歷每一個文件,進(jìn)行輸出 for (File file : files) {zipOutputStream.putNextEntry(new ZipEntry(file.getName()));FileInputStream fileInputStream = new FileInputStream(file);int readLen;byte[] buffer = new byte[1024];while ((readLen = fileInputStream.read(buffer)) != -1) { zipOutputStream.write(buffer, 0, readLen);}// 關(guān)閉流fileInputStream.close();zipOutputStream.closeEntry(); } } finally { if (null != zipOutputStream) {try { zipOutputStream.close();} catch (IOException ex) { ex.printStackTrace();} } } }

測試,將D盤下的infp.txt和infp1.txt文件壓縮到D盤下,壓縮文件名為my.zip。

public static void main(String[] args) throws Exception { zipMultipleFiles('D:/my.zip', new File('D:/infp.txt'), new File('D:/infp1.txt')); }2.2 壓縮文件或文件樹

此方法將文件夾下的所有文件按原有的樹形結(jié)構(gòu)壓縮到文件中,也支持壓縮單個文件。原理也簡單,無非就是遞歸遍歷文件樹中的每一個文件,進(jìn)行壓縮。有個注意的點(diǎn)每一個文件的寫入路徑是基于壓縮文件位置的相對路徑。

package com.nobody.zip;import java.io.*;import java.util.zip.ZipEntry;import java.util.zip.ZipInputStream;import java.util.zip.ZipOutputStream;public class ZipUtils { /** * 壓縮文件或文件夾(包括所有子目錄文件) * * @param sourceFile 源文件 * @param format 格式(zip或rar) * @throws IOException 異常信息 */ public static void zipFileTree(File sourceFile, String format) throws IOException { ZipOutputStream zipOutputStream = null; try { String zipFileName; if (sourceFile.isDirectory()) { // 目錄zipFileName = sourceFile.getParent() + File.separator + sourceFile.getName() + '.' + format; } else { // 單個文件zipFileName = sourceFile.getParent() + sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf('.')) + '.' + format; } // 壓縮輸出流 zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName)); zip(sourceFile, zipOutputStream, ''); } finally { if (null != zipOutputStream) {// 關(guān)閉流try { zipOutputStream.close();} catch (IOException ex) { ex.printStackTrace();} } } } /** * 遞歸壓縮文件 * * @param file 當(dāng)前文件 * @param zipOutputStream 壓縮輸出流 * @param relativePath 相對路徑 * @throws IOException IO異常 */ private static void zip(File file, ZipOutputStream zipOutputStream, String relativePath) throws IOException { FileInputStream fileInputStream = null; try { if (file.isDirectory()) { // 當(dāng)前為文件夾// 當(dāng)前文件夾下的所有文件File[] list = file.listFiles();if (null != list) { // 計算當(dāng)前的相對路徑 relativePath += (relativePath.length() == 0 ? '' : '/') + file.getName(); // 遞歸壓縮每個文件 for (File f : list) { zip(f, zipOutputStream, relativePath); }} } else { // 壓縮文件// 計算文件的相對路徑relativePath += (relativePath.length() == 0 ? '' : '/') + file.getName();// 寫入單個文件zipOutputStream.putNextEntry(new ZipEntry(relativePath));fileInputStream = new FileInputStream(file);int readLen;byte[] buffer = new byte[1024];while ((readLen = fileInputStream.read(buffer)) != -1) { zipOutputStream.write(buffer, 0, readLen);}zipOutputStream.closeEntry(); } } finally { // 關(guān)閉流 if (fileInputStream != null) {try { fileInputStream.close();} catch (IOException ex) { ex.printStackTrace();} } } } public static void main(String[] args) throws Exception { String path = 'D:/test'; String format = 'zip'; zipFileTree(new File(path), format); }}

上例將test目錄下的所有文件壓縮到同一目錄下的test.zip文件中。

2.3 借助文件訪問器壓縮

還有一種更簡單的方式,我們不自己寫遞歸遍歷。借助Java原生類,SimpleFileVisitor,它提供了幾個訪問文件的方法,其中有個方法visitFile,對于文件樹中的每一個文件(文件夾除外),都會調(diào)用這個方法。我們只要寫一個類繼承SimpleFileVisitor,然后重寫visitFile方法,實(shí)現(xiàn)將每一個文件寫入到壓縮文件中即可。

當(dāng)然,除了visitFile方法,它里面還有preVisitDirectory,postVisitDirectory,visitFileFailed等方法,通過方法名大家也猜出什么意思了。

package com.nobody.zip;import java.io.FileOutputStream;import java.io.IOException;import java.nio.file.*;import java.nio.file.attribute.BasicFileAttributes;import java.util.zip.ZipEntry;import java.util.zip.ZipOutputStream;/** * @Description * @Author Mr.nobody * @Date 2021/3/8 * @Version 1.0.0 */public class ZipFileTree extends SimpleFileVisitor<Path> { // zip輸出流 private ZipOutputStream zipOutputStream; // 源目錄 private Path sourcePath; public ZipFileTree() {} /** * 壓縮目錄以及所有子目錄文件 * * @param sourceDir 源目錄 */ public void zipFile(String sourceDir) throws IOException { try { // 壓縮后的文件和源目錄在同一目錄下 String zipFileName = sourceDir + '.zip'; this.zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName)); this.sourcePath = Paths.get(sourceDir); // 開始遍歷文件樹 Files.walkFileTree(sourcePath, this); } finally { // 關(guān)閉流 if (null != zipOutputStream) {zipOutputStream.close(); } } } // 遍歷到的每一個文件都會執(zhí)行此方法 @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException { // 取相對路徑 Path targetFile = sourcePath.relativize(file); // 寫入單個文件 zipOutputStream.putNextEntry(new ZipEntry(targetFile.toString())); byte[] bytes = Files.readAllBytes(file); zipOutputStream.write(bytes, 0, bytes.length); zipOutputStream.closeEntry(); // 繼續(xù)遍歷 return FileVisitResult.CONTINUE; } // 遍歷每一個目錄時都會調(diào)用的方法 @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { return super.preVisitDirectory(dir, attrs); } // 遍歷完一個目錄下的所有文件后,再調(diào)用這個目錄的方法 @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { return super.postVisitDirectory(dir, exc); } // 遍歷文件失敗后調(diào)用的方法 @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { return super.visitFileFailed(file, exc); } public static void main(String[] args) throws IOException { // 需要壓縮源目錄 String sourceDir = 'D:/test'; // 壓縮 new ZipFileTree().zipFile(sourceDir); }}三 解壓文件

解壓壓縮包,借助ZipInputStream類,可以讀取到壓縮包中的每一個文件,然后根據(jù)讀取到的文件屬性,寫入到相應(yīng)路徑下即可。對于解壓壓縮包中是文件樹的結(jié)構(gòu),每讀取到一個文件后,如果是多層路徑下的文件,需要先創(chuàng)建父目錄,再寫入文件流。

package com.nobody.zip;import java.io.*;import java.util.zip.ZipEntry;import java.util.zip.ZipInputStream;import java.util.zip.ZipOutputStream;/** * @Description 解壓縮文件工具類 * @Author Mr.nobody * @Date 2021/3/8 * @Version 1.0.0 */public class ZipUtils { /** * 解壓 * * @param zipFilePath 帶解壓文件 * @param desDirectory 解壓到的目錄 * @throws Exception */ public static void unzip(String zipFilePath, String desDirectory) throws Exception { File desDir = new File(desDirectory); if (!desDir.exists()) { boolean mkdirSuccess = desDir.mkdir(); if (!mkdirSuccess) {throw new Exception('創(chuàng)建解壓目標(biāo)文件夾失敗'); } } // 讀入流 ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath)); // 遍歷每一個文件 ZipEntry zipEntry = zipInputStream.getNextEntry(); while (zipEntry != null) { if (zipEntry.isDirectory()) { // 文件夾String unzipFilePath = desDirectory + File.separator + zipEntry.getName();// 直接創(chuàng)建mkdir(new File(unzipFilePath)); } else { // 文件String unzipFilePath = desDirectory + File.separator + zipEntry.getName();File file = new File(unzipFilePath);// 創(chuàng)建父目錄mkdir(file.getParentFile());// 寫出文件流BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(unzipFilePath));byte[] bytes = new byte[1024];int readLen;while ((readLen = zipInputStream.read(bytes)) != -1) { bufferedOutputStream.write(bytes, 0, readLen);}bufferedOutputStream.close(); } zipInputStream.closeEntry(); zipEntry = zipInputStream.getNextEntry(); } zipInputStream.close(); } // 如果父目錄不存在則創(chuàng)建 private static void mkdir(File file) { if (null == file || file.exists()) { return; } mkdir(file.getParentFile()); file.mkdir(); } public static void main(String[] args) throws Exception { String zipFilePath = 'D:/test.zip'; String desDirectory = 'D:/a'; unzip(zipFilePath, desDirectory); }}四 總結(jié)

在解壓縮文件過程中,主要是對流的讀取操作,注意進(jìn)行異常處理,以及關(guān)閉流。web應(yīng)用中,通過接口可以實(shí)現(xiàn)文件上傳下載,對應(yīng)的我們只要把壓縮后的文件,寫入到response.getOutputStream()輸出流即可。解壓縮文件時,注意空文件夾的處理。

此演示項(xiàng)目已上傳到Github,如有需要可自行下載,歡迎 Star 。 https://github.com/LucioChn/common-utils

以上就是Java 如何實(shí)現(xiàn)解壓縮文件和文件夾的詳細(xì)內(nèi)容,更多關(guān)于Java 解壓縮文件和文件夾的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 刚性-柔性防水套管-橡胶伸缩接头-波纹管补偿器-启腾供水材料有限公司 | 镀锌钢格栅_热镀锌格栅板_钢格栅板_热镀锌钢格板-安平县昊泽丝网制品有限公司 | 南京种植牙医院【官方挂号】_南京治疗种植牙医院那个好_南京看种植牙哪里好_南京茀莱堡口腔医院 尼龙PA610树脂,尼龙PA612树脂,尼龙PA1010树脂,透明尼龙-谷骐科技【官网】 | 披萨石_披萨盘_电器家电隔热绵加工定制_佛山市南海区西樵南方综合保温材料厂 | 小学教案模板_中学教师优秀教案_高中教学设计模板_教育巴巴 | 江西高职单独招生-江西单招考试-江西高职单招网 | 不锈钢螺丝,不锈钢螺栓,不锈钢标准件-江苏百德特种合金有限公司 交变/复合盐雾试验箱-高低温冲击试验箱_安奈设备产品供应杭州/江苏南京/安徽马鞍山合肥等全国各地 | 刑事律师_深圳著名刑事辩护律师_王平聚【清华博士|刑法教授】 | 纯化水设备-纯水设备-超纯水设备-[大鹏水处理]纯水设备一站式服务商-东莞市大鹏水处理科技有限公司 | 小港信息港-鹤壁信息港 鹤壁老百姓便民生活信息网站 | 杭州画室_十大画室_白墙画室_杭州美术培训_国美附中培训_附中考前培训_升学率高的画室_美术中考集训美术高考集训基地 | 旅游规划_旅游策划_乡村旅游规划_景区规划设计_旅游规划设计公司-北京绿道联合旅游规划设计有限公司 | 绿萝净除甲醛|深圳除甲醛公司|测甲醛怎么收费|培训机构|电影院|办公室|车内|室内除甲醛案例|原理|方法|价格立马咨询 | 山东石英砂过滤器,除氟过滤器「价格低」-淄博胜达水处理 | 祝融环境-地源热泵多恒系统高新技术企业,舒适生活环境缔造者! | 制丸机,小型中药制丸机,全自动制丸机价格-甘肃恒跃制药设备有限公司 | 除尘布袋_液体过滤袋_针刺毡滤料-杭州辉龙过滤技术有限公司 | 水性绝缘漆_凡立水_绝缘漆树脂_环保绝缘漆-深圳维特利环保材料有限公司 | 澳威全屋定制官网|极简衣柜十大品牌|衣柜加盟代理|全屋定制招商 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 纸箱抗压机,拉力机,脂肪测定仪,定氮仪-山东德瑞克仪器有限公司 | 存包柜厂家_电子存包柜_超市存包柜_超市电子存包柜_自动存包柜-洛阳中星 | 合肥钣金加工-安徽激光切割加工-机箱机柜加工厂家-合肥通快 | [品牌官网]贵州遵义双宁口腔连锁_贵州遵义牙科医院哪家好_种植牙_牙齿矫正_原华美口腔 | 香港新时代国际美容美发化妆美甲培训学校-26年培训经验,值得信赖! | 咖啡加盟-咖啡店加盟-咖啡西餐厅加盟-塞纳左岸咖啡西餐厅官网 | 酶联免疫分析仪-多管旋涡混合仪|混合器-莱普特科学仪器(北京)有限公司 | 动库网动库商城-体育用品专卖店:羽毛球,乒乓球拍,网球,户外装备,运动鞋,运动包,运动服饰专卖店-正品运动品网上商城动库商城网 - 动库商城 | 滚筒烘干机_转筒烘干机_滚筒干燥机_转筒干燥机_回转烘干机_回转干燥机-设备生产厂家 | 氧氮氢联合测定仪-联测仪-氧氮氢元素分析仪-江苏品彦光电 | 欧景装饰设计工程有限公司-无锡欧景装饰官网 | 二氧化碳/活性炭投加系统,次氯酸钠发生器,紫外线消毒设备|广州新奥 | 香蕉筛|直线|等厚|弧形|振动筛|香蕉筛厂家-洛阳隆中重工 | 精雕机-火花机-精雕机 cnc-高速精雕机-电火花机-广东鼎拓机械科技有限公司 | 马尔表面粗糙度仪-MAHR-T500Hommel-Mitutoyo粗糙度仪-笃挚仪器 | 网站建设-网站制作-网站设计-网站开发定制公司-网站SEO优化推广-咏熠软件 | 昆明挖掘机修理厂_挖掘机翻新再制造-昆明聚力工程机械维修有限公司 | 化妆品加工厂-化妆品加工-化妆品代加工-面膜加工-广东欧泉生化科技有限公司 | 净化工程_无尘车间_无尘车间装修-广州科凌净化工程有限公司 | 禹城彩钢厂_钢结构板房_彩钢复合板-禹城泰瑞彩钢复合板加工厂 | 快干水泥|桥梁伸缩缝止水胶|伸缩缝装置生产厂家-广东广航交通科技有限公司 | 聚氨酯催化剂K15,延迟催化剂SA-1,叔胺延迟催化剂,DBU,二甲基哌嗪,催化剂TMR-2,-聚氨酯催化剂生产厂家 |