大数据Java基础(一)-文档归档与解档

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;
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlexZ分不清堆栈

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值