zoukankan      html  css  js  c++  java
  • 大数据开发之文件归档和解归档

    一,归档

    在大数据开发中往往要运算海量数据,可是这些数据分布在许多小文件中,传输和运算十分不方便,为此我们得进行文件归档

    即把几个小文件写到一个文件中形成大文件,可是我们要怎么写呢?每个团队有每个团队的方法,下面介绍我自己的方法。

                        格式:        4个字节        文件名称的数据存储大小(n,表示存储的文件有几个字节)

                                           n个字节        文件名称

                                           4个字节        文件内容的数据存储大小(m,表示存储的文件有几个字节)

                                           m个字节        文件内容

                       有几个小文件,那么归档后的文件就有多少个这样的格式。

    第一步 定义一个函数,使用4个字节,存储 文件名称的数据存储大小,归档的时候使用,看代码

    public byte[] int2Bytes(int i)
        {
            byte[] arr = new byte[4];
            arr[0]=(byte)i;
            arr[1]=(byte)(i>>8);
            arr[1]=(byte)(i>>8);
            arr[1]=(byte)(i>>8);
            return arr;
        }

    第2步定义一个函数,把这4个字节的二进制数据转换成我们能看懂的数据,解归档的时候用

    public int Bytes2int(byte bytes[])
        {
            int i0=bytes[0] & 0xFF;     //byte类型运算时会自动转成int类型,为了防止字节数据的第一位为1而导致扩充后前面全补1导致正数变负数
            int i1 = (bytes[1] & 0xFF) << 8 ; 
            int i2 = (bytes[2] & 0xFF) << 16 ;
            int i3 = (bytes[3] & 0xFF) << 24 ;
            return i0 | i1 | i2 | i3 ;    
        }

    归档代码如下

    package 归档;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class Archivee {
    
        public static void main(String[] args) throws Exception {
                FileOutputStream fos = new FileOutputStream("d:/arch/x.xar");
                fos.write(addFile("D:/arch/a.xls"));
                fos.write(addFile("D:/arch/b.xml"));
                fos.write(addFile("D:/arch/c.txt"));
                fos.close();
        }
        public static byte[] addFile(String path) throws Exception
        {
            //文件路径
            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);
            }
            fis.close();
            //得到文件内容
            byte[] fcontentArr = baos.toByteArray();
            System.arraycopy(fcontentArr, 0, bytes, 4 + fnameBytes.length + 4 , fcontentArr.length);
            return bytes;    
         }
    }

    三,解归档

    首先要定义一个实体类来存储文件名称和文件内容,然后放到List集合中,然后同一写出去。

    package 归档;
    
    class FileBean {
         private String fileName;
         private byte[] fileContent;
         
         
        public FileBean() {
            
        }
        public FileBean(String fileName, byte[] fileContent) {
        
            this.fileName = fileName;
            this.fileContent = 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;
        }
         
         
    }

    具体代码:

    package 归档;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    
    
    public class UnArchiver {
    
        public static void main(String[] args)throws Exception {
            List<FileBean> files = new ArrayList<FileBean>();
            
            FileInputStream fis = new FileInputStream("d:/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("d:/arch/unarch/"+fb.getFileName());
                fos.write(fb.getFileContent());
                fos.close();
            }
        }
        
        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 fname = new String(fileNameBytes);
            
            //再读取4个字节作为文件内容的长度
            fis.read(bytes4);
            int fileContentLen = Util.Bytes2int(bytes4);
            
            //读取文件内容
            byte[] fileContentBytes = new byte[fileContentLen];
            fis.read(fileContentBytes);
            
            return new FileBean(fname,fileContentBytes);
            
        }
    }
  • 相关阅读:
    微软程序员最好的时代来了
    领域驱动设计系列 (六):CQRS
    当我谈 "加班有罪" 我在谈什么?
    parquet 简介(转)
    Spark动态资源分配-Dynamic Resource Allocation
    Spark配置参数详解
    PhpStorm使用sftp实现代码自动上传服务器
    docker 命令大全
    mysql 5.6配置
    docker volume
  • 原文地址:https://www.cnblogs.com/ithome0222/p/8729177.html
Copyright © 2011-2022 走看看