生活随笔
收集整理的這篇文章主要介紹了
Java压缩技术(七) TAR——Commons实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載自? ?Java壓縮技術(七) TAR——Commons實現
順便復習一遍linux命令:? tar cf <file.tar> <file> 將由文件<file>創建名為<file.tar>歸檔文件,同時保留原文件。? tar xf <file.tar> 將由歸檔文件<file.tar>創建名為<file>的文件/目錄,同時保留原文件。? 對于歸檔壓縮,需分為gzip和bzip2,相應的linux為:? gzip ? tar czf <file.tar.gz> <file> 將由文件<file>創建名為<file.tar.gz>歸檔壓縮文件,同時保留原文件。? tar xzf <file.tar.gz> 將由歸檔壓縮文件<file.tar.gz>創建名為<file>的文件/目錄,同時保留原文件。? bzip2 ? tar cjf <file.tar.bz2> <file> 將由文件<file>創建名為<file.tar.bz2>歸檔壓縮文件,同時保留原文件。? tar xjf <file.tar.bz2> 將由歸檔壓縮文件<file.tar.bz2>創建名為<file>的文件/目錄,同時保留原文件。? 今天的主角是Apache Commons Compress下用于Tar操作的三元干將? TarArchiveEntry ?類似于Java 原生的ZipEntry,可以理解為Tar歸檔添加項。? TarArchiveOutputStream? Tar歸檔輸出流,用于歸檔。? TarArchiveInputStream? Tar歸檔輸入流,用于解歸檔。? 至于jar,其實現方式與tar非常接近,我就不在這里廢話了! JarArchiveEntry ?類似于Java 原生的ZipEntry,可以理解為Jar歸檔添加項。? JarArchiveOutputStream? Jar歸檔輸出流,用于歸檔。? JarArchiveInputStream? Jar歸檔輸入流,用于解歸檔。? 讀過 Java壓縮技術(二)和 Java壓縮技術(三)會發現,其實Tar的實現與Java原生的Zip實現方式基本上沒有差別! 先說歸檔,依舊需要考慮待歸檔的對象是文件還是目錄:?
Java代碼??
? ? ? ? ? ? ? ? ? ? ?? private ?static ?void ?archive(File?srcFile,?TarArchiveOutputStream?taos,??????????String?basePath)?throws ?Exception?{?? ????if ?(srcFile.isDirectory())?{?? ????????archiveDir(srcFile,?taos,?basePath);?? ????}?else ?{?? ????????archiveFile(srcFile,?taos,?basePath);?? ????}?? }??
對于目錄,需要區分空目錄和包含文件的目錄。?
如果是空目錄,只要簡單追加一個歸檔項(TarArchiveEntry)即可,但注意其名字的結尾需要使用"/"作為區分目錄的標識符(String PATH = "/";)。?
如果是帶有子文件的目錄,則需要對其迭代歸檔:?
Java代碼??
? ? ? ? ? ? ? ? ?? private ?static ?void ?archiveDir(File?dir,?TarArchiveOutputStream?taos,??????????String?basePath)?throws ?Exception?{?? ?? ????File[]?files?=?dir.listFiles();?? ?? ????if ?(files.length?<?1 )?{?? ????????TarArchiveEntry?entry?=?new ?TarArchiveEntry(basePath?? ????????????????+?dir.getName()?+?PATH);?? ?? ????????taos.putArchiveEntry(entry);?? ????????taos.closeArchiveEntry();?? ????}?? ?? ????for ?(File?file?:?files)?{?? ?? ?????????? ????????archive(file,?taos,?basePath?+?dir.getName()?+?PATH);?? ?? ????}?? }??
最后,來看歸檔操作:?
Java代碼?
? ? ? ? ? ? ? ? ? ? ? ? ?? private ?static ?void ?archiveFile(File?file,?TarArchiveOutputStream?taos,??????????String?dir)?throws ?Exception?{?? ?? ????TarArchiveEntry?entry?=?new ?TarArchiveEntry(dir?+?file.getName());?? ?? ????entry.setSize(file.length());?? ?? ????taos.putArchiveEntry(entry);?? ?? ????BufferedInputStream?bis?=?new ?BufferedInputStream(new ?FileInputStream(?? ????????????file));?? ????int ?count;?? ????byte ?data[]?=?new ?byte [BUFFER];?? ????while ?((count?=?bis.read(data,?0 ,?BUFFER))?!=?-1 )?{?? ????????taos.write(data,?0 ,?count);?? ????}?? ?? ????bis.close();?? ?? ????taos.closeArchiveEntry();?? }??
注意執行歸檔操作后,執行closeArchiveEntry()方法。?
Tar解歸檔,與Zip解壓相似,一樣要遍歷獲得歸檔項:?
Java代碼?
? ? ? ? ? ? ? ? ?? private ?static ?void ?dearchive(File?destFile,?TarArchiveInputStream?tais)??????????throws ?Exception?{?? ?? ????TarArchiveEntry?entry?=?null ;?? ????while ?((entry?=?tais.getNextTarEntry())?!=?null )?{?? ?? ?????????? ????????String?dir?=?destFile.getPath()?+?File.separator?+?entry.getName();?? ?? ????????File?dirFile?=?new ?File(dir);?? ?? ?????????? ????????fileProber(dirFile);?? ?? ????????if ?(entry.isDirectory())?{?? ????????????dirFile.mkdirs();?? ????????}?else ?{?? ????????????dearchiveFile(dirFile,?tais);?? ????????}?? ?? ????}?? }??
最后,進行解歸檔:?
Java代碼?
? ? ? ? ? ? ? ? ?? private ?static ?void ?dearchiveFile(File?destFile,?TarArchiveInputStream?tais)??????????throws ?Exception?{?? ?? ????BufferedOutputStream?bos?=?new ?BufferedOutputStream(?? ????????????new ?FileOutputStream(destFile));?? ?? ????int ?count;?? ????byte ?data[]?=?new ?byte [BUFFER];?? ????while ?((count?=?tais.read(data,?0 ,?BUFFER))?!=?-1 )?{?? ????????bos.write(data,?0 ,?count);?? ????}?? ?? ????bos.close();?? }??
文件探針用于構建父目錄:?
Java代碼?
? ? ? ? ? ? ? ? ?? private ?static ?void ?fileProber(File?dirFile)?{???? ????File?parentFile?=?dirFile.getParentFile();?? ????if ?(!parentFile.exists())?{?? ?? ?????????? ????????fileProber(parentFile);?? ?? ????????parentFile.mkdir();?? ????}?? ?? }??
給出完整實現:?
Java代碼?
? ? ?? package ?org.zlex.commons.compress;???? import ?java.io.BufferedInputStream;??import ?java.io.BufferedOutputStream;??import ?java.io.File;??import ?java.io.FileInputStream;??import ?java.io.FileOutputStream;???? import ?org.apache.commons.compress.archivers.tar.TarArchiveEntry;??import ?org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;??import ?org.apache.commons.compress.archivers.tar.TarArchiveInputStream;???? ? ? ? ? ? ?? public ?abstract ?class ?TarUtils?{???? ????private ?static ?final ?String?BASE_DIR?=?"" ;?? ?? ?????? ????private ?static ?final ?String?PATH?=?"/" ;?? ????private ?static ?final ?int ?BUFFER?=?1024 ;?? ?? ????private ?static ?final ?String?EXT?=?".tar" ;?? ?? ????? ? ? ? ? ? ?? ????public ?static ?void ?archive(String?srcPath,?String?destPath)?? ????????????throws ?Exception?{?? ?? ????????File?srcFile?=?new ?File(srcPath);?? ?? ????????archive(srcFile,?destPath);?? ?? ????}?? ?? ????? ? ? ? ? ? ? ? ?? ????public ?static ?void ?archive(File?srcFile,?File?destFile)?throws ?Exception?{?? ?? ????????TarArchiveOutputStream?taos?=?new ?TarArchiveOutputStream(?? ????????????????new ?FileOutputStream(destFile));?? ?? ????????archive(srcFile,?taos,?BASE_DIR);?? ?? ????????taos.flush();?? ????????taos.close();?? ????}?? ?? ????? ? ? ? ? ?? ????public ?static ?void ?archive(File?srcFile)?throws ?Exception?{?? ????????String?name?=?srcFile.getName();?? ????????String?basePath?=?srcFile.getParent();?? ????????String?destPath?=?basePath?+?name?+?EXT;?? ????????archive(srcFile,?destPath);?? ????}?? ?? ????? ? ? ? ? ? ?? ????public ?static ?void ?archive(File?srcFile,?String?destPath)?throws ?Exception?{?? ????????archive(srcFile,?new ?File(destPath));?? ????}?? ?? ????? ? ? ? ? ?? ????public ?static ?void ?archive(String?srcPath)?throws ?Exception?{?? ????????File?srcFile?=?new ?File(srcPath);?? ?? ????????archive(srcFile);?? ????}?? ?? ????? ? ? ? ? ? ? ? ? ? ?? ????private ?static ?void ?archive(File?srcFile,?TarArchiveOutputStream?taos,?? ????????????String?basePath)?throws ?Exception?{?? ????????if ?(srcFile.isDirectory())?{?? ????????????archiveDir(srcFile,?taos,?basePath);?? ????????}?else ?{?? ????????????archiveFile(srcFile,?taos,?basePath);?? ????????}?? ????}?? ?? ????? ? ? ? ? ? ? ? ?? ????private ?static ?void ?archiveDir(File?dir,?TarArchiveOutputStream?taos,?? ????????????String?basePath)?throws ?Exception?{?? ?? ????????File[]?files?=?dir.listFiles();?? ?? ????????if ?(files.length?<?1 )?{?? ????????????TarArchiveEntry?entry?=?new ?TarArchiveEntry(basePath?? ????????????????????+?dir.getName()?+?PATH);?? ?? ????????????taos.putArchiveEntry(entry);?? ????????????taos.closeArchiveEntry();?? ????????}?? ?? ????????for ?(File?file?:?files)?{?? ?? ?????????????? ????????????archive(file,?taos,?basePath?+?dir.getName()?+?PATH);?? ?? ????????}?? ????}?? ?? ????? ? ? ? ? ? ? ? ? ? ? ? ?? ????private ?static ?void ?archiveFile(File?file,?TarArchiveOutputStream?taos,?? ????????????String?dir)?throws ?Exception?{?? ?? ????????? ? ? ? ? ? ? ?? ????????TarArchiveEntry?entry?=?new ?TarArchiveEntry(dir?+?file.getName());?? ?? ????????entry.setSize(file.length());?? ?? ????????taos.putArchiveEntry(entry);?? ?? ????????BufferedInputStream?bis?=?new ?BufferedInputStream(new ?FileInputStream(?? ????????????????file));?? ????????int ?count;?? ????????byte ?data[]?=?new ?byte [BUFFER];?? ????????while ?((count?=?bis.read(data,?0 ,?BUFFER))?!=?-1 )?{?? ????????????taos.write(data,?0 ,?count);?? ????????}?? ?? ????????bis.close();?? ?? ????????taos.closeArchiveEntry();?? ????}?? ?? ????? ? ? ? ? ?? ????public ?static ?void ?dearchive(File?srcFile)?throws ?Exception?{?? ????????String?basePath?=?srcFile.getParent();?? ????????dearchive(srcFile,?basePath);?? ????}?? ?? ????? ? ? ? ? ? ?? ????public ?static ?void ?dearchive(File?srcFile,?File?destFile)?throws ?Exception?{?? ?? ????????TarArchiveInputStream?tais?=?new ?TarArchiveInputStream(?? ????????????????new ?FileInputStream(srcFile));?? ????????dearchive(destFile,?tais);?? ?? ????????tais.close();?? ?? ????}?? ?? ????? ? ? ? ? ? ?? ????public ?static ?void ?dearchive(File?srcFile,?String?destPath)?? ????????????throws ?Exception?{?? ????????dearchive(srcFile,?new ?File(destPath));?? ?? ????}?? ?? ????? ? ? ? ? ? ? ? ?? ????private ?static ?void ?dearchive(File?destFile,?TarArchiveInputStream?tais)?? ????????????throws ?Exception?{?? ?? ????????TarArchiveEntry?entry?=?null ;?? ????????while ?((entry?=?tais.getNextTarEntry())?!=?null )?{?? ?? ?????????????? ????????????String?dir?=?destFile.getPath()?+?File.separator?+?entry.getName();?? ?? ????????????File?dirFile?=?new ?File(dir);?? ?? ?????????????? ????????????fileProber(dirFile);?? ?? ????????????if ?(entry.isDirectory())?{?? ????????????????dirFile.mkdirs();?? ????????????}?else ?{?? ????????????????dearchiveFile(dirFile,?tais);?? ????????????}?? ?? ????????}?? ????}?? ?? ????? ? ? ? ? ? ? ?? ????public ?static ?void ?dearchive(String?srcPath)?throws ?Exception?{?? ????????File?srcFile?=?new ?File(srcPath);?? ?? ????????dearchive(srcFile);?? ????}?? ?? ????? ? ? ? ? ? ? ? ?? ????public ?static ?void ?dearchive(String?srcPath,?String?destPath)?? ????????????throws ?Exception?{?? ?? ????????File?srcFile?=?new ?File(srcPath);?? ????????dearchive(srcFile,?destPath);?? ????}?? ?? ????? ? ? ? ? ? ? ? ?? ????private ?static ?void ?dearchiveFile(File?destFile,?TarArchiveInputStream?tais)?? ????????????throws ?Exception?{?? ?? ????????BufferedOutputStream?bos?=?new ?BufferedOutputStream(?? ????????????????new ?FileOutputStream(destFile));?? ?? ????????int ?count;?? ????????byte ?data[]?=?new ?byte [BUFFER];?? ????????while ?((count?=?tais.read(data,?0 ,?BUFFER))?!=?-1 )?{?? ????????????bos.write(data,?0 ,?count);?? ????????}?? ?? ????????bos.close();?? ????}?? ?? ????? ? ? ? ? ? ? ? ?? ????private ?static ?void ?fileProber(File?dirFile)?{?? ?? ????????File?parentFile?=?dirFile.getParentFile();?? ????????if ?(!parentFile.exists())?{?? ?? ?????????????? ????????????fileProber(parentFile);?? ?? ????????????parentFile.mkdir();?? ????????}?? ?? ????}?? ?? }??
最后給出測試用例:?
Java代碼??
? ? ?? package ?org.zlex.commons.compress;???? import ?static ?org.junit.Assert.*;???? import ?java.io.DataInputStream;??import ?java.io.File;??import ?java.io.FileInputStream;??import ?java.io.FileOutputStream;???? import ?org.junit.Before;??import ?org.junit.Test;???? ? ? ? ? ? ?? public ?class ?TarUtilsTest?{??????private ?String?inputStr;?? ????private ?String?name?=?"data.xml" ;?? ?? ????@Before ?? ????public ?void ?before()?{?? ????????StringBuilder?sb?=?new ?StringBuilder();?? ????????sb.append("<?xml?version=\"1.0\"?encoding=\"utf-8\"??>" );?? ????????sb.append("\r\n" );?? ????????sb.append("<dataGroup>" );?? ????????sb.append("\r\n\t" );?? ????????sb.append("<dataItem>" );?? ????????sb.append("\r\n\t\t" );?? ????????sb.append("<data>" );?? ????????sb.append("Test" );?? ????????sb.append("</data>" );?? ????????sb.append("\r\n\t" );?? ????????sb.append("<dataItem>" );?? ????????sb.append("\r\n" );?? ????????sb.append("</dataGroup>" );?? ?? ????????inputStr?=?sb.toString();?? ????}?? ?? ????@Test ?? ????public ?void ?testArchiveFile()?throws ?Exception?{?? ?? ????????byte []?contentOfEntry?=?inputStr.getBytes();?? ?? ????????String?path?=?"d:/" ?+?name;?? ?? ????????FileOutputStream?fos?=?new ?FileOutputStream(path);?? ?? ????????fos.write(contentOfEntry);?? ????????fos.flush();?? ????????fos.close();?? ?? ????????TarUtils.archive(path);?? ?? ????????TarUtils.dearchive(path?+?".tar" );?? ?? ????????File?file?=?new ?File(path);?? ?? ????????FileInputStream?fis?=?new ?FileInputStream(file);?? ?? ????????DataInputStream?dis?=?new ?DataInputStream(fis);?? ?? ????????byte []?data?=?new ?byte [(int )?file.length()];?? ?? ????????dis.readFully(data);?? ?? ????????fis.close();?? ?? ????????String?outputStr?=?new ?String(data);?? ????????assertEquals(inputStr,?outputStr);?? ?? ????}?? ?? ????@Test ?? ????public ?void ?testArchiveDir()?throws ?Exception?{?? ????????String?path?=?"d:/fd" ;?? ????????TarUtils.archive(path);?? ?? ????????TarUtils.dearchive(path?+?".tar" ,?"d:/fds" );?? ????}?? ?? }??
執行代碼,來看下效果:?
?
這是原始文件。?
?
這是歸檔后的文件。?
注意紅框,這里沒有經過任何壓縮!
?
除了tar、zip,其實還有很多歸檔算法,如ar、jar、cpio。其實現方式,與上述內容較為接近。?
至于壓縮成*.tar.gz、*.tar.bz2,請朋友們參照前幾篇內容!
TarUtils.rar?(2.4 KB) 下載次數: 482
總結
以上是生活随笔 為你收集整理的Java压缩技术(七) TAR——Commons实现 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。