大資料Java基礎(一)-文件歸檔與解檔
阿新 • • 發佈:2019-01-22
hadoop中如日誌檔案、天氣記錄文件等都是以文件的形式儲存資料。而大量儲存文件,就會涉及到將有共同特點或者相似性的文件歸為一類等(如按照年份將相同年份的天氣資料文件歸為一類)。
從而需要我們對文件的歸檔和解檔有一定了解。
歸檔就是將多個有共同點的文件歸為一個大的文件;解檔就是將一個大文件,分解成多個獨立的文件。
這裡先普及一下基礎:多個文件歸為一個時,需要確定文件名稱、文件內容,定義文件名稱長度、文件內容長度。順序是定義好文件名稱長度,往裡面寫名稱,在定義好文件內容長度,往裡面加文件內容,然後下一個文件加在這個文件後面步驟和上一個文件一樣。
解檔就是歸檔的逆推。
下面廢話不多說直接上程式
首先是型別轉換工具類就是我上一章的內容
** * @ClassName Util * @Decription 型別轉換工具類 * @Author AlexZ * @Date 2018-8-1 14:17 * @Version 1.0 */ public class Util { /** * 整型轉換成位元組陣列 */ public static byte[] int2Bytes(int i){ byte[] arr = new byte[4]; arr[0] = (byte) i; arr[1] = (byte) (i >> 8); arr[2] = (byte) (i >> 16); arr[3] = (byte) (i >> 24); return arr ; } /** * 位元組陣列轉換成int */ public static int bytes2Int(byte[] bytes){ int i0 = bytes[0] & 0xFF; int i1 = (bytes[1] & 0xFF) << 8; int i2 = (bytes[2] & 0xFF) << 16; int i3 = (bytes[3] & 0xFF) << 24; return i0 | i1 | i2 | i3; } }
然後是文件的歸檔器
import java.io.*; /** * @ClassName Arcchiver * @Decription 歸檔器 * @Author AlexZ * @Date 2018-8-1 13:57 * @Version 1.0 */ public class Arcchiver { public static void main(String[] args) throws Exception{ // FileOutputStream fos = new FileOutputStream("g:/arch/x.xar",true); fos.write(addFile("G:/arch/a.xls")); fos.write(addFile("G:/arch/b.java")); fos.close(); // } /** * path : g:/xxx/xxx/a.jpg */ public static byte[] addFile(String path) throws IOException{ //檔案 File f = new File(path); //檔名 String fname = f.getName(); //檔名陣列 byte[] fnameBytes = fname.getBytes(); //檔案內容長度 int len = (int)f.length(); //計算總長度 int total = 4 + fnameBytes.length + 4 +len ; //初始化總陣列 byte[] bytes = new byte[total]; //1.寫入檔名長度 byte[] fnameLenArr = Util.int2Bytes(fnameBytes.length); System.arraycopy(fnameLenArr,0, bytes,0,4); //2.寫入檔名本身 System.arraycopy(fnameBytes,0, bytes,4, fnameBytes.length); //3.寫入檔案內容長度 byte[] fcontentLenArr = Util.int2Bytes(len); System.arraycopy(fcontentLenArr,0,bytes,4+fnameBytes.length, 4); //4.寫入檔案內容本身 //讀取檔案內容到陣列中 ByteArrayOutputStream baos = new ByteArrayOutputStream(); FileInputStream fis = new FileInputStream(f); byte[] buf = new byte[1024]; int len0 = 0; while ((len0 = fis.read(buf)) != -1){ baos.write(buf,0,len0); } //得到檔案內容 byte[] fileContentArr = baos.toByteArray(); System.arraycopy(fileContentArr,0 ,bytes,8 + fnameBytes.length, fileContentArr.length); return bytes; } }
最後是解析器
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName Unarchiver
* @Decription 解析器
* @Author AlexZ
* @Date 2018-8-1 17:09
* @Version 1.0
*/
public class Unarchiver {
public static void main(String[] args) throws Exception{
List<FileBean> files = new ArrayList<FileBean>();
//
FileInputStream fis = new FileInputStream("g:/arch/x.xar");
FileBean fileBean = null;
//
while ((fileBean = readNextFile(fis)) != null) {
files.add(fileBean);
}
//關閉流
fis.close();
FileOutputStream fos = null;
//
for (FileBean fb : files){
fos = new FileOutputStream("g:/arch/unarch/"+fb.getFileName());
fos.write(fb.getFileContent());
fos.close();
}
}
/**
* 從流中讀取下一個檔案
* @param fis
* @return
*/
public static FileBean readNextFile(FileInputStream fis) throws Exception{
//
byte[] bytes4 = new byte[4];
//讀取四個位元組
int res = fis.read(bytes4);
if (res == -1){
return null;
}
//檔名長度
int fnameLen = Util.bytes2Int(bytes4);
//檔名陣列
byte[] fileNameBytes = new byte[fnameLen];
fis.read(fileNameBytes);
//得到檔名
String fileName = new String(fileNameBytes);
//在讀取4個位元組,作為檔案內容長度
fis.read(bytes4);
int fileContLen = Util.bytes2Int(bytes4);
//讀取檔案內容
byte[] fileContBytes = new byte[fileContLen];
fis.read(fileContBytes);
return new FileBean(fileName,fileContBytes);
}
}
最後是中間用到的FileBean類
/**
* @ClassName FileBean
* @Decription 檔案Bean
* @Author AlexZ
* @Date 2018-8-1 20:02
* @Version 1.0
*/
public class FileBean {
private String fileName;
private byte[] fileContent;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public byte[] getFileContent() {
return fileContent;
}
public void setFileContent(byte[] fileContent) {
this.fileContent = fileContent;
}
public FileBean(){
}
public FileBean(String fileName, byte[] fileContent) {
this.fileName = fileName;
this.fileContent = fileContent;
}
}