最近接到一個需求,做個進程,涉及去某台服務器上面取tar.gz壓縮文件,然后進行解壓。
奈何自己沒搞過類似的需求。自己很懵逼。最后一番波折寫出以下代碼。
謹做個人筆記。
知識前提:
1、tar.gz為后綴的文件是一種壓縮文件,在Linux和macOS下常見,Linux和macOS都可以直接解壓使用這種壓縮文件。但是我們是要從Java!扯什么Linux和macOS!!!!
2、自測代碼,可以通過自己壓縮一個tar.gz壓縮包。壓縮工具推薦7-zip。先tar壓縮,再gzip壓縮。
3、先使用GZIPInputStream讀取文件(為什么要先用GZIPInputStream,建議參考tar.gz文件是怎么生成,個人理解。)。生成文件,再進行使用FileInputStream和FileOutputStream文件流進行讀文件和寫文件。
4、類TarEntry
隸屬於 Apcache org.apache.tools.tar 包的一個類。
這個類TarEntry表示Tar歸檔文件中的條目。它由條目的標題和條目的File組成。
從存檔中讀取的標頭字節創建的TarEntries使用TarEntry(byte [])構造函數實例化。從存檔內容中提取或列出存檔內容時,將使用這些條目。
TarEntries只能由名稱構成。這使程序員可以手動構造條目。
一,處理解tar.gz壓縮包.主要方法。

1 /** 2 * 處理壓縮包並獲取文件Name 3 * @param fileName 4 * @return 5 */ 6 private List<String> processSingleZipFile(String zipFileName) throws Exception { 7 if(log.isInfoEnabled()){ 8 log.info("開始解壓["+zipFileName+"]*************"); 9 } 10 List<String> retFiles=null; 11 try { 12 String tarFile = zipFileName.substring(0, zipFileName.indexOf(".gz")); 13 this.unZip(this.localPath + File.separator + zipFileName, this.localPath + File.separator + tarFile); 14 retFiles = this.unTar(this.localPath + File.separator + tarFile, this.localPath + File.separator); 15 // move to his 16 File gzFile = new File(this.localPath+ File.separator + zipFileName); 17 File gzHisFile = new File(this.localPath + File.separator + zipFileName); 18 gzFile.renameTo(gzHisFile); 19 gzFile.delete();//把解壓包移到HIS目錄 20 } catch (Exception e) { 21 if(log.isErrorEnabled()){ 22 log.error("解壓文件"+zipFileName+"失敗!", e); 23 } 24 } 25 return retFiles; 26 }
二、邏輯代碼一。

1 /** 2 * 讀取壓縮包 3 * 4 * @param zipFile 5 * @param destFile 6 * @throws Exception 7 */ 8 protected void unZip(String zipFile, String destFile) throws Exception { 9 File file = new File(zipFile); 10 FileInputStream fin = new FileInputStream(file); 11 GZIPInputStream gzis = new GZIPInputStream(fin); 12 File zfile = new File(destFile); 13 FileOutputStream fout = new FileOutputStream(zfile); 14 byte[] buf = new byte[1024]; 15 int number = gzis.read(buf, 0, buf.length); 16 while (number != -1) { 17 fout.write(buf, 0, number); 18 number = gzis.read(buf, 0, buf.length); 19 } 20 close(gzis); 21 close(fout); 22 close(fin); 23 24 }
三,邏輯代碼二。

1 /** 2 * 解壓壓縮包 3 * 4 * @param zipFile 5 * @param destFile 6 * @throws Exception 7 */ 8 protected List<String> unTar(String tarFile, String destDir) throws Exception 9 { 10 11 List<String> retFiles = new ArrayList<>(); 12 InputStream inputstream = null; 13 OutputStream outputstream = null; 14 TarInputStream zis = null; 15 File file = null; 16 try { 17 file = new File(tarFile); 18 inputstream = new FileInputStream(file); 19 zis = new TarInputStream(inputstream); 20 TarEntry tarEntry; 21 while ((tarEntry = zis.getNextEntry()) != null) { 22 retFiles.add(tarEntry.getName()); //添加解壓縮之后的文件名,類的頭目 23 File tempFile = new File(destDir + tarEntry.getName()); 24 tempFile.createNewFile(); 25 outputstream = new FileOutputStream(tempFile); 26 byte[] buf = new byte[1024*50]; 27 int readsize = zis.read(buf, 0, buf.length); 28 while (readsize != -1) { 29 outputstream.write(buf, 0, readsize); 30 readsize = zis.read(buf, 0, buf.length); 31 } 32 outputstream.flush(); 33 outputstream.close(); 34 } 35 } catch (Exception e) { 36 log.error("error:", e); 37 throw e; 38 } finally { 39 if (null != outputstream) { 40 outputstream.flush(); 41 } 42 if (null != inputstream) { 43 inputstream.close(); 44 } 45 if (null != zis) { 46 zis.close(); 47 } 48 if (null != outputstream) { 49 outputstream.close(); 50 } 51 if (null != file) { 52 file.delete(); 53 } 54 } 55 return retFiles; 56 57 }