java實現(xiàn)文件歸檔和還原
本文實例為大家分享了java實現(xiàn)文件歸檔和還原的具體代碼,供大家參考,具體內(nèi)容如下
基本思路:
文件歸檔,換句話就是把多個文件的字節(jié)存到一個文件中。為此我們必須定義存儲格式,才能從包中把文件重新抽出來。
文件由文件名和內(nèi)容組成。要想完整的還原文件,我們必須同時存下這兩個東西,而文件名和內(nèi)容的字節(jié)大小我們都是不知道的,為此我們必須要用固定大小的空間存儲它們的大小。
存儲格式

代碼實現(xiàn)
因為文件內(nèi)容大小是4個字節(jié)(也就是int型),我們要把它存到文件,就要轉(zhuǎn)化成字節(jié)數(shù)組。我們規(guī)定低位靠前,高位靠后。按照這種格式封裝轉(zhuǎn)換操作與一個基礎(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é)在進行移位運算時,首先會被轉(zhuǎn)換成int類型,
//此時若字節(jié)的符號位為1,它前面就會補全1,比如:
//0x80在byte類型時是-128,而轉(zhuǎn)換成int,它的值還是
//-128,即0xffffff80,而我們移位運算想要的是
//0x00000080,即前面補全0,跟我們拆時一致。為此,
//我們讓它與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三個文件。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis-plus分頁查詢?nèi)N方法小結(jié)
本文主要介紹了mybatis-plus分頁查詢?nèi)N方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
springboot+element-ui實現(xiàn)多文件一次上傳功能
這篇文章主要介紹了springboot+element-ui多文件一次上傳功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-06-06
Java基于堆結(jié)構(gòu)實現(xiàn)優(yōu)先隊列功能示例
這篇文章主要介紹了Java基于堆結(jié)構(gòu)實現(xiàn)優(yōu)先隊列功能,結(jié)合實例形式分析了java優(yōu)先隊列的簡單定義與使用方法,需要的朋友可以參考下2017-11-11
spring boot配置讀寫分離的完整實現(xiàn)步驟
數(shù)據(jù)庫配置主從之后,如何在代碼層面實現(xiàn)讀寫分離?所以下面這篇文章主要給大家介紹了關(guān)于spring boot配置讀寫分離的完整步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2018-09-09

