亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Java 如何實現解壓縮文件和文件夾

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

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

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

二 壓縮文件

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

壓縮文件操作,會使用到一個類,即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)); // 遍歷每一個文件,進行輸出 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);}// 關閉流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 壓縮文件或文件樹

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

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) {// 關閉流try { zipOutputStream.close();} catch (IOException ex) { ex.printStackTrace();} } } } /** * 遞歸壓縮文件 * * @param file 當前文件 * @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()) { // 當前為文件夾// 當前文件夾下的所有文件File[] list = file.listFiles();if (null != list) { // 計算當前的相對路徑 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 { // 關閉流 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,對于文件樹中的每一個文件(文件夾除外),都會調用這個方法。我們只要寫一個類繼承SimpleFileVisitor,然后重寫visitFile方法,實現將每一個文件寫入到壓縮文件中即可。

當然,除了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 { // 關閉流 if (null != zipOutputStream) {zipOutputStream.close(); } } } // 遍歷到的每一個文件都會執行此方法 @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(); // 繼續遍歷 return FileVisitResult.CONTINUE; } // 遍歷每一個目錄時都會調用的方法 @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { return super.preVisitDirectory(dir, attrs); } // 遍歷完一個目錄下的所有文件后,再調用這個目錄的方法 @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { return super.postVisitDirectory(dir, exc); } // 遍歷文件失敗后調用的方法 @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類,可以讀取到壓縮包中的每一個文件,然后根據讀取到的文件屬性,寫入到相應路徑下即可。對于解壓壓縮包中是文件樹的結構,每讀取到一個文件后,如果是多層路徑下的文件,需要先創建父目錄,再寫入文件流。

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('創建解壓目標文件夾失敗'); } } // 讀入流 ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath)); // 遍歷每一個文件 ZipEntry zipEntry = zipInputStream.getNextEntry(); while (zipEntry != null) { if (zipEntry.isDirectory()) { // 文件夾String unzipFilePath = desDirectory + File.separator + zipEntry.getName();// 直接創建mkdir(new File(unzipFilePath)); } else { // 文件String unzipFilePath = desDirectory + File.separator + zipEntry.getName();File file = new File(unzipFilePath);// 創建父目錄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(); } // 如果父目錄不存在則創建 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); }}四 總結

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

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

以上就是Java 如何實現解壓縮文件和文件夾的詳細內容,更多關于Java 解壓縮文件和文件夾的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
主站蜘蛛池模板: 看一级毛片一区二区三区免费 | 美女视频黄a视频免费全过程 | 国产三级视频在线观看视主播 | 1819高清欧美xx | 中文字幕一区在线播放 | 极品销魂一区二区三区 | 国产精品久久久久影院 | 国产成人综合久久亚洲精品 | 亚洲人视频 | 国产黄色一级片 | 欧美亚洲日本一区二区三区浪人 | 91私密视频 | 欧美日韩国产亚洲综合不卡 | 老外一级黄色片 | 综合区小说区图片区在线一区 | 成人午夜国产福到在线不卡 | 精品欧美日韩一区二区三区 | 久久综合中文字幕 | 国产精品视频区 | 一区二区三区四区无限乱码 | 欧美精品综合 | 国产夜色福利院在线观看免费 | 日韩 欧美 中文字幕 不卡 | 亚洲精品久久一区影院 | 国产网站麻豆精品视频 | 乱色美www女麻豆 | 国产一区二区三区免费 | 久久国产免费 | 伊人久久久久久久久香港 | 亚欧洲精品在线视频免费观看 | 日韩在线精品视频 | 欧美日韩国产另类一区二区三区 | 国产精品福利无圣光在线一区 | 欧美αv日韩αv亚洲αv在线观看 | 黄色毛片免费在线观看 | 香港性特级黄录像片 | 亚洲欧美综合 | 播播网手机在线播放 | 久久久社区 | 欧美毛片免费观看 | 久久机热这里只有精品无需 |