本節摘要:本節摘要介紹對文件的壓縮。
1.引言
之前在 壓縮與解壓1---字符串的壓縮與解壓(http://www.cnblogs.com/java-pan/archive/2012/05/12/gzip1.html)
中介紹過對字符串的壓縮和解壓,這個解壓和解決用在系統之間大數據傳輸的時候還是可以大大的減少網絡流量的。本節主要本別介紹對單個文件、多個文件的壓縮。解壓這里就不講了,解壓的話沒什么實際意義,因為文件壓縮后為zip格式的文件,現在windows系統解壓這個格式的文件真是特多了。我個人認為這個壓縮文件的功能在以下場景使用就比較合理:比如某運行的系統,在每天或者每周的固定時間會導出一批報表,如果我們不對導出的報表進行壓縮,那么磁盤空間會大幅度的增加,如果我們對導出的文件進行壓縮,那么磁盤空間的開銷就會大大節省。
2.文件壓縮的中文問題
中文,一直是個頭疼的問題,同樣,在這里我們對文件壓縮也會出現中文亂碼問題。對壓縮的文件,如果文件名稱是中文,壓縮完成后,可以看到壓縮包中的文件名稱是亂碼(文件的內容有中文,壓縮后不會出現中文亂碼問題),對於這種情況我們只要用ANT中的ant.jar中的類就可以解決此問題。壓縮過程中會用到ZipEntry和ZipOutputStream類,如果我采用第一種方式,這樣就會出現中文亂碼;如果我采用第二種方式,中文亂碼問題就可以解決。文件運行的對比效果我會在后面把截圖貼出來做一下對比。
第一種方式:
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
以上采用JDK API中自帶的類時壓縮的文件名會出現中文亂碼
第二種方式:
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
以上采用ANT中ant.jar包的類可以解決壓縮的文件名的中文亂碼問題
3.下載jar包
對於本節我只需要一個jar包,即ant.jar,提供jar包的下載路徑如下:
http://files.cnblogs.com/java-pan/jar-ant.rar
4.method&class
ZipEntry:
ZipOutputStream:
5.代碼文件
ZipFileUtil.java

1 package zip; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 8 /* 9 * 采用JDK API中自帶的類時壓縮的文件會出現中文亂碼 10 */ 11 //import java.util.zip.ZipEntry; 12 //import java.util.zip.ZipOutputStream; 13 14 /* 15 * 采用ANT中ant.jar包的類可以解決中文亂碼問題 16 */ 17 import org.apache.tools.zip.ZipEntry; 18 import org.apache.tools.zip.ZipOutputStream; 19 20 /** 21 *Module: ZipFileUtil.java 22 *Description: 用zip對單個和多個文件進行壓縮 23 *Company: xxx 24 *Version: 1.0.0 25 *Author: pantp 26 *Date: May 24, 2012 27 */ 28 public class ZipFileUtil { 29 30 public static void main(String[] args) throws Exception { 31 32 /* 33 * 測試單個文件的ZIP壓縮 34 * 指定文件路徑可以是絕對路徑,也可以是相對路徑 35 */ 36 String file = "src/zip/文件1.txt"; 37 String zipFile1 = "src/zip/單個文件壓縮.zip"; 38 boolean flag1 = zipSingleFile(file, zipFile1); 39 System.out.println("\n**************壓縮【單】個文件<author:pantp>******************************\n"); 40 if (flag1) { 41 System.out.println("單個文件ZIP壓縮成功,壓縮后文件所在路徑為:"+zipFile1); 42 } else { 43 System.out.println("單個文件ZIP壓縮失敗"); 44 } 45 System.out.println("\n*******************************************************************************"); 46 47 /* 48 * 測試多個文件的ZIP壓縮 49 * 指定文件路徑可以是絕對路徑,也可以是相對路徑 50 */ 51 /* String files[] = { "src/zip/文件1.txt", "src/zip/file2.txt" }; 52 String zipFile2 = "src/zip/多個文件壓縮.zip"; 53 boolean flag2 = zipFiles(files, zipFile2); 54 System.out.println("\n**************壓縮【多】個文件<author:pantp>******************************\n"); 55 if (flag2) { 56 System.out.println("多個文件ZIP壓縮成功,壓縮后文件所在路徑為:"+zipFile2); 57 } else { 58 System.out.println("多個文件ZIP壓縮失敗"); 59 } 60 System.out.println("\n*******************************************************************************"); 61 */ 62 } 63 64 /** 65 *<p> 66 *@param file 待壓縮文件的名稱 例如,src/zip/文件1.txt 67 *@param zipFile 壓縮后文件的名稱 例如,src/zip/單個文件壓縮.zip 68 *@return boolean 69 *@throws :IOException 70 *@Function: zipSingleFile 71 *@Description:單個文件的壓縮 72 *@version : v1.0.0 73 *@author: pantp 74 *@Date:May 24, 2012 75 *</p> 76 *Modification History: 77 * Date Author Version Description 78 * --------------------------------------------------------------------- 79 * May 24, 2012 pantp v1.0.0 Create 80 */ 81 public static boolean zipSingleFile(String file, String zipFile) 82 throws IOException { 83 boolean bf = true; 84 File f = new File(file); 85 if (!f.exists()) { 86 System.out.println("文件不存在"); 87 bf = false; 88 } else { 89 File ff = new File(zipFile); 90 if (!f.exists()) { 91 ff.createNewFile(); 92 } 93 // 創建文件輸入流對象 94 FileInputStream in = new FileInputStream(file); 95 // 創建文件輸出流對象 96 FileOutputStream out = new FileOutputStream(zipFile); 97 // 創建ZIP數據輸出流對象 98 ZipOutputStream zipOut = new ZipOutputStream(out); 99 // 得到文件名稱 100 String fileName = file.substring(file.lastIndexOf('/') + 1, file.length()); 101 // 創建指向壓縮原始文件的入口 102 ZipEntry entry = new ZipEntry(fileName); 103 zipOut.putNextEntry(entry); 104 // 向壓縮文件中輸出數據 105 int number = 0; 106 byte[] buffer = new byte[512]; 107 while ((number = in.read(buffer)) != -1) { 108 zipOut.write(buffer, 0, number); 109 } 110 zipOut.close(); 111 out.close(); 112 in.close(); 113 } 114 return bf; 115 } 116 117 /** 118 *<p> 119 *@param files 待壓縮的文件列表 例如,src/zip/文件1.txt, src/zip/file2.txt 120 *@param zipfile 壓縮后的文件名稱 例如,src/zip/多個文件壓縮.zip 121 *@return boolean 122 *@throws :Exception 123 *@Function: zipFiles 124 *@Description:多個文件的ZIP壓縮 125 *@version : v1.0.0 126 *@author: pantp 127 *@Date:May 24, 2012 128 *</p> 129 *Modification History: 130 * Date Author Version Description 131 * --------------------------------------------------------------------- 132 * May 24, 2012 pantp v1.0.0 Create 133 */ 134 public static boolean zipFiles(String[] files, String zipfile) 135 throws Exception { 136 boolean bf = true; 137 138 // 根據文件路徑構造一個文件實例 139 File ff = new File(zipfile); 140 // 判斷目前文件是否存在,如果不存在,則新建一個 141 if (!ff.exists()) { 142 ff.createNewFile(); 143 } 144 // 根據文件路徑構造一個文件輸出流 145 FileOutputStream out = new FileOutputStream(zipfile); 146 // 傳入文件輸出流對象,創建ZIP數據輸出流對象 147 ZipOutputStream zipOut = new ZipOutputStream(out); 148 149 // 循環待壓縮的文件列表 150 for (int i = 0; i < files.length; i++) { 151 File f = new File(files[i]); 152 if (!f.exists()) { 153 bf = false; 154 } 155 try { 156 // 創建文件輸入流對象 157 FileInputStream in = new FileInputStream(files[i]); 158 // 得到當前文件的文件名稱 159 String fileName = files[i].substring( 160 files[i].lastIndexOf('/') + 1, files[i].length()); 161 // 創建指向壓縮原始文件的入口 162 ZipEntry entry = new ZipEntry(fileName); 163 zipOut.putNextEntry(entry); 164 // 向壓縮文件中輸出數據 165 int nNumber = 0; 166 byte[] buffer = new byte[512]; 167 while ((nNumber = in.read(buffer)) != -1) { 168 zipOut.write(buffer, 0, nNumber); 169 } 170 // 關閉創建的流對象 171 in.close(); 172 } catch (IOException e) { 173 e.printStackTrace(); 174 bf = false; 175 } 176 } 177 zipOut.close(); 178 out.close(); 179 return bf; 180 } 181 182 }
6.運行測試
(1)在項目的src的zip目錄下新建以下2個測試文件
文件1.txt
file2.txt
(2)運行main方法中單個文件壓縮的方法,運行結果如圖:
后台日志如下:
生成的zip文件如下:
*(
(3)運行main方法中多個文件壓縮的方法,運行結果如圖:
后台日志如下:
生成的zip文件如下:
壓縮后的文件中不會出現中文亂碼問題,打開多個文件壓縮.zip文件中的文件1.txt,內容如下:
采用JDK自帶的類會出現中文亂碼問題,效果如圖: