java實(shí)現(xiàn)文件歸檔和還原
本文實(shí)例為大家分享了java實(shí)現(xiàn)文件歸檔和還原的具體代碼,供大家參考,具體內(nèi)容如下
基本思路:
文件歸檔,換句話就是把多個(gè)文件的字節(jié)存到一個(gè)文件中。為此我們必須定義存儲(chǔ)格式,才能從包中把文件重新抽出來。
文件由文件名和內(nèi)容組成。要想完整的還原文件,我們必須同時(shí)存下這兩個(gè)東西,而文件名和內(nèi)容的字節(jié)大小我們都是不知道的,為此我們必須要用固定大小的空間存儲(chǔ)它們的大小。
存儲(chǔ)格式
代碼實(shí)現(xiàn)
因?yàn)槲募?nèi)容大小是4個(gè)字節(jié)(也就是int型),我們要把它存到文件,就要轉(zhuǎn)化成字節(jié)數(shù)組。我們規(guī)定低位靠前,高位靠后。按照這種格式封裝轉(zhuǎn)換操作與一個(gè)基礎(chǔ)類DataUtil中。
DataUtil代碼
package util; public class DataUtil { public static byte[] int2bytes(int src) { byte[] rt = new byte[4]; for(int i=0; i<4; ++i) { rt[i] = (byte)(src>>(i*8)); } return rt; } public static int bytes2int(byte[] src) { int rt = 0; for(int i=0; i<4; ++i) { rt |= (src[i]&0xFF)<<(i*8); //字節(jié)在進(jìn)行移位運(yùn)算時(shí),首先會(huì)被轉(zhuǎn)換成int類型, //此時(shí)若字節(jié)的符號(hào)位為1,它前面就會(huì)補(bǔ)全1,比如: //0x80在byte類型時(shí)是-128,而轉(zhuǎn)換成int,它的值還是 //-128,即0xffffff80,而我們移位運(yùn)算想要的是 //0x00000080,即前面補(bǔ)全0,跟我們拆時(shí)一致。為此, //我們讓它與0xFF相與,從0xffffff80變?yōu)?x00000080。 } return rt; } }
歸檔類
package wfb.binSama; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import util.DataUtil; /** * @author binSama */ public class Archive { public static void archive(File[] srcs,File tar) {//歸檔 try { FileOutputStream fos = new FileOutputStream(tar); for(int i=0; i<srcs.length; ++i) { //獲得文件名 byte[] fileName = srcs[i].getName().getBytes(); //獲得文件名長度 byte fileNameLen = (byte)fileName.length; //獲得文件內(nèi)容 FileInputStream fis = new FileInputStream(srcs[i]); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int len = -1; byte[] buf = new byte[1024]; while((len = fis.read(buf)) != -1) { baos.write(buf, 0, len); } baos.close(); fis.close(); byte[] fileContent = baos.toByteArray(); //獲得文件內(nèi)容長度 byte[] fileContentLen = DataUtil.int2bytes(fileContent.length); //寫入 fos.write(fileNameLen); fos.write(fileName); fos.write(fileContentLen); fos.write(fileContent); } fos.close(); } catch (Exception e) { e.printStackTrace(); } } public static void unArchive(File src) {//解檔到當(dāng)前文件夾 try { FileInputStream fis = new FileInputStream(src); int fileNameLen = -1; while((fileNameLen = fis.read()) != -1){ byte[] byteFileName = new byte[fileNameLen]; fis.read(byteFileName); String fileName = src.getParent() +"\\"+ new String(byteFileName); FileOutputStream fos = new FileOutputStream(fileName); byte[] byteFileContentLen = new byte[4]; fis.read(byteFileContentLen); int fileContentLen = DataUtil.bytes2int(byteFileContentLen); int divisorFileContentLen = fileContentLen / 1024; int remainderFileContentLen = fileContentLen % 1024; ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] divisorBuf = new byte[1024]; for(int i=0; i<divisorFileContentLen; ++i) { fis.read(divisorBuf); baos.write(divisorBuf); } byte[] remainderBuf = new byte[remainderFileContentLen]; fis.read(remainderBuf); baos.write(remainderBuf); baos.close(); byte[] fileContent = baos.toByteArray(); fos.write(fileContent); } fis.close(); } catch (Exception e) { e.printStackTrace(); } } }
測試:
package wfb.binSama; import java.io.File; public class Test { @org.junit.Test public void test() { File[] files = new File[3]; files[0] = new File("E:\\waster\\Archiver1\\1.txt"); files[1] = new File("E:\\waster\\Archiver1\\2.png"); files[2] = new File("E:\\waster\\Archiver1\\3.txt"); File bsm = new File("E:\\waster\\Archiver2\\archive.bsm"); Archive.archive(files, bsm); Archive.unArchive(bsm); } }
現(xiàn)象
成功在E:\waster\Archiver2文件夾生成了archive.bsm歸檔文件,并解檔出1.txt 2.png 3.txt三個(gè)文件。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能
這篇文章主要為大家詳細(xì)介紹了SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03關(guān)于Java利用反射實(shí)現(xiàn)動(dòng)態(tài)運(yùn)行一行或多行代碼
這篇文章主要介紹了關(guān)于Java利用反射實(shí)現(xiàn)動(dòng)態(tài)運(yùn)行一行或多行代碼,借鑒了別人的方法和書上的內(nèi)容,最后將題目完成了,和大家一起分享以下解決方法,需要的朋友可以參考下2023-04-04elasticsearch如何根據(jù)條件刪除數(shù)據(jù)
Elasticsearch是一個(gè)基于Apache Lucene?的開源搜索引擎,無論在開源還是專有領(lǐng)域,Lucene 可以被認(rèn)為是迄今為止最先進(jìn)、性能最好的、功能最全的搜索引擎庫,這篇文章主要介紹了elasticsearch如何根據(jù)條件刪除數(shù)據(jù),需要的朋友可以參考下2023-03-03springboot swagger 接口文檔分組展示功能實(shí)現(xiàn)
這篇文章主要介紹了springboot swagger 接口文檔分組展示功能實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-03-03