Java中zip文件壓縮與解壓之ZipInputStream和ZipOutputStream
文件壓縮 ZipOutputStream
用ZipOutputStream來壓縮一個文件夾時,要搭配ZipEntry來使用。ZipEntry是用來創(chuàng)建壓縮文件的。
舉個例子,向壓縮文件中添加一個文件的代碼:
//zipOut:壓縮文件的路徑 ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipOut)); //zipOutputStream.putNextEntry() ====> 向壓縮包中添加一個文件 //new ZipEntry("text1.txt") ======? zip壓縮包中文件都是用ZipEntry對象, //"text1.txt"===》是文件在壓縮文件的路徑,text1.txt表示在壓縮文件的根路徑 zipOutputStream.putNextEntry(new ZipEntry("text1.txt"));
如下圖:
在創(chuàng)建ZipEntry對象時可以指定文件在壓縮包的位置:new ZipEntry(“second-dir\second-01.txt”)
在使用ZipOutputStream壓縮文件時要注意的地方就是這些,下面給一個壓縮文件的代碼:
static final int BUFFER_SIZE = 4 << 10; /** * 壓縮指定目錄下的所有文件 * @param dir 指定壓縮目錄 * @param destZipName 指定壓縮包名字 */ public void zip(String dir,String zipPath,String destZipName) throws IOException { File file = new File(dir); /**1.為zip文件創(chuàng)建目錄*****/ String path = file.getParentFile().getAbsolutePath(); if(isNull(destZipName))destZipName = file.getName()+".zip"; if(isNull(zipPath)) zipPath = path; String zipOut = zipPath + File.separator + destZipName; File zipOutFile = new File(zipOut); if(!zipOutFile.getParentFile().exists()){ zipOutFile.getParentFile().mkdirs(); } /**為zip文件創(chuàng)建目錄*****/ ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipOut)); if(!file.isDirectory())zipOutputStream.close(); File[] subFiles = file.listFiles(); for (File subFile : subFiles) { buildZipDir(zipOutputStream,subFile,null); } zipOutputStream.close(); } void buildZipDir(ZipOutputStream zipOut,File file,String baseDir) throws IOException { if(file.isFile()){ String zipEntryName = baseDir == null ? file.getName() : baseDir+File.separator+file.getName(); zipOut.putNextEntry(new ZipEntry(zipEntryName)); byte[] buffer = new byte[BUFFER_SIZE]; try(InputStream inputStream = new FileInputStream(file)){ int len = -1; while((len = inputStream.read(buffer)) != -1){ zipOut.write(buffer,0,len); } zipOut.flush(); zipOut.closeEntry(); } } else{//文件是dir,繼續(xù)遞歸找文件 File[] subFiles = file.listFiles(); if(subFiles.length ==0){//處理空文件夾 String zipName = baseDir == null ? file.getName() :baseDir + File.separator+ file.getName() ; zipOut.putNextEntry(new ZipEntry(zipName)); zipOut.closeEntry(); }else{ for (File subFile : subFiles) { String subBaseDir =baseDir == null ? file.getName() :baseDir + File.separator+ file.getName() ; buildZipDir(zipOut,subFile,subBaseDir); } } } } public boolean isNull(String str){ return str == null || str.equals(""); }
測試:
@Test public void testZip() throws IOException { String dir = "D:\\test-zip"; //dir : 要壓縮的目錄 //D:\\yy\\ 指定壓縮文件的位置 //path-test.zip 指定壓縮文件的名字 zip(dir,"D:\\yy\\","path-test.zip"); }
文件解壓:ZipInputStream
ZipInputStream讀取壓縮文件,配合ZipFile使用;通過上面的例子,我們知道壓縮包里的是一個個ZipEntry對象,在解壓時,可以遍歷壓縮包獲取到ZipEntry對象。每一個ZipEntry對象都是一個文件,使用ZipFile可以獲取到每一個ZipEntry對象的文件流;獲取到文件流就可以將壓縮包的文件讀出來了。
public void unZip(String zipPath,String unzipPath) throws IOException { File file = new File(zipPath); ZipFile zipFile = new ZipFile(file);//zip文件 ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file)); if(isNull(unzipPath))unzipPath = zipPath.replace(".zip",""); ZipEntry nextEntry = null; while( (nextEntry = zipInputStream.getNextEntry()) != null){ String name = nextEntry.getName(); String fileOutPath = unzipPath + File.separator + name; File fileOut = new File(fileOutPath); if(!fileOut.getParentFile().exists()){ fileOut.getParentFile().mkdirs(); } if(!fileOut.exists()){ fileOut.createNewFile(); } OutputStream output = new FileOutputStream(fileOutPath); InputStream inputStream = zipFile.getInputStream(nextEntry);//通過ZipFile獲取到ZipEntry的文件流 int read = -1; byte[] buffer = new byte[BUFFER_SIZE]; while((read = inputStream.read(buffer) ) != -1){ output.write(buffer,0, read); } output.flush(); output.close(); inputStream.close(); } zipInputStream.close(); zipFile.close(); }
測試:
public void testUnzip() throws IOException { String zip = "D:\\yy\\path-test.zip"; unZip(zip,null); }
總結(jié)
到此這篇關(guān)于Java中zip文件壓縮與解壓之ZipInputStream和ZipOutputStream的文章就介紹到這了,更多相關(guān)Java zip文件壓縮解壓內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis plus關(guān)閉駝峰命名的四種方法(防止出現(xiàn)查詢?yōu)镹ull)
這篇文章主要介紹了Mybatis plus關(guān)閉駝峰命名的四種方法(防止出現(xiàn)查詢?yōu)镹ull),數(shù)據(jù)庫的字段命名方式為使用下劃線連接,對應(yīng)的實體類應(yīng)該是駝峰命名方式,而我使用的是和數(shù)據(jù)庫同樣的命名方式,需要的朋友可以參考下2022-01-01Mybatis-plus使用TableNameHandler分表詳解(附完整示例源碼)
這篇文章主要介紹了Mybatis-plus使用TableNameHandler分表詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01這一次搞懂Spring代理創(chuàng)建及AOP鏈?zhǔn)秸{(diào)用過程操作
這篇文章主要介紹了這一次搞懂Spring代理創(chuàng)建及AOP鏈?zhǔn)秸{(diào)用過程操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08Java中YYYY-MM-dd與yyyy-MM-dd的區(qū)別及跨年問題
YYYY-MM-dd可能會導(dǎo)致跨年周的日期被歸屬到錯誤的年份, yyyy-MM-dd總是表示實際的日歷年份,無論日期所在的周是否跨年,本文就來介紹一下兩者的區(qū)別,感興趣的可以了解一下2024-01-01