大数据开发之文件归档和解归档

一,归档

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

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

格式:        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);

    }
}

原文地址:https://www.cnblogs.com/ithome0222/p/8729177.html

时间: 2024-10-28 23:36:39

大数据开发之文件归档和解归档的相关文章

iOS:文件归档和解归档的详解和使用

文件归档和解归档: 用途: 所谓文件归档,就是把需要存储的对象数据存储到沙盒的Documents目录下的文件中,即存储到了磁盘上,实现数据的持久性存储和备份.解归档,就是从磁盘上读取该文件下的数据,用来完成用户的需求.对象归档是将对象归档以文件的形式保存到磁盘中(也称为序列化,持久化),使用的时候读取该文件的保存路径的读取文件的内容(也称为接档,反序列化),(对象归档的文件是保密的,在磁盘上无法查看文件中的内容,而属性列表是明文的,可以查看). 区别: 通过文件归档产生的文件是不可见的,如果打开

【OC学习-28】自定义对象的归档和解归档:例子说明以及简单总结

对对象进行归档,和对对象进行拷贝差不多路数,也就是需要协议,之前的时对NSString和NSNumber这些对象为什么没有归档协议?因为它们自带了. 所以如果我们要对自定义的对象(而不是Foundation里默认的对象)进行归档的话就需要引入归档协议<NSCoding>. 举例:声明一个User类,然后创建一个对象user1,把这个user1进行归档,然后把归档后的文件解归档到user2中,看看是否是原先的那些数据. (1)User.h #import <Foundation/Found

将通讯录类(姓名、电话),添加归档和解归档方法,即,添加储存信息到磁盘的方法。

/*1.将通讯录类(姓名.电话),添加归档和解归档方法,即,添加储存信息到磁盘的方法.*/ #import <Foundation/Foundation.h>#import "ConTact.h"#define PATH @"/Users/qianfeng/Desktop/hehe/2.plist" int main(int argc, const char * argv[]) {    @autoreleasepool {        ConTact

基于大数据开发套件定时调度带资源文件的MapReduce作业

MaxCompute里的MR作业,很少是只要跑一次就好了的.如果需要周期性调度,目前MaxCompute(原名ODPS)只提供了计算引擎,任务调度可以使用大数据开发套件来实现.这篇帖子从基础开始,介绍了3种周期性调度的方法.同时还介绍了如何使用资源文件. 代码开发 代码以文档里的WordCount 作为例子.在这个基础上,增加资源文件的读取方法,修改Reduce类.主要的逻辑是读取资源文件,资源文件里的数据格式是字符串1,字符串2.代码逻辑是如果word count里的word如果有在字符串1里

Spark修炼之道(基础篇)——Linux大数据开发基础:第一节、Linux介绍、安装及使用初步

本节主要内容 Linux简史 Linux特点 Ubuntu Linux安装 Linux使用初步 1. Linux简史 要讲述大名鼎鼎的Linux,必然要先从UNIX系统谈起,下面这幅图给出了Unix系统的进化图: 图片来源:http://baike.baidu.com/link?url=QfoqWtWGs-BjpnfEy_AUk7Bm3XHuf6JbN92HCOoUBfFfj8BuSDkbwmldtmUEmGRDUwqsQMIV4jCKHvdkSPr3Lq 从进化图中可以看到,目前所有的主流操作

大数据开发常用的大数据分析软件有什么?

大数据开发常用的大数据分析软件有什么? 大数据研究的出现,为企业.研究机构.政府决策提供了新的行之有效思路和手段,想要做好大数据的管理和分析,一些大数据开发工具的使用是必不可少的,以下是大数据开发过程中常用的工具: 1. Apache Hive Hive是一个建立在Hadoop上的开源数据仓库基础设施,通过Hive可以很容易的进行数据的ETL,对数据进行结构化处理,并对Hadoop上大数据文件进行查询和处理等. Hive提供了一种简单的类似SQL的查询语言-HiveQL,这为熟悉SQL语言的用户

为什么要学习React,学习React在大数据开发上有什么好处

为什么要学习React,学习React在大数据开发上有什么好处 分享之前我还是要推荐下我自己创建的大数据学习资料分享群716581014,这是全国最大的大数据学习交流的地方,2000人聚集,不管你是小白还是大牛,小编我都挺欢迎,今天的源码已经上传到群文件,不定期分享干货,包括我自己整理的一份最新的适合2018年学习和零基础入门教程,欢迎初学和进阶中的小伙伴. 如何学习React 如果你是一个 React (或者前端) 新手, 出于以下的原因, 你可能会对这个生态圈感到困惑: React 的目标群

大数据好学习吗?如何快速掌握大数据开发技能

大数据好学习吗?如何快速掌握大数据开发技能?经常被学员问到:大数据好学吗?想学大数据怕学不会等问题.我想说的是,大数据在当下是个非常热门的话题,大数据在深刻的影响着这个世界,在促进传统行业升级改造.引领新兴产业和新兴应用蓬勃发展.提升社会运行和管理效率等方面,大数据正引发新一轮革命.大数据是时代潮流,如果学一下就会了,那大数据行业现在恐怕已经被挤破门槛了吧,想学大数据还是得下苦功夫才行. 想学大数据,先把这几个技能学会再说: Apache Hive2.1 Hive是建立在Hadoop上的数据仓库

2018年最新Hadoop大数据开发学习路线图

Hadoop发展到今天家族产品已经非常丰富,能够满足不同场景的大数据处理需求.作为目前主流的大数据处理技术,市场上很多公司的大数据业务都是基于Hadoop开展,而且对很多场景已经具有非常成熟的解决方案. 作为开发人员掌握Hadoop及其生态内框架的开发技术,就是进入大数据领域的必经之路. 下面详细介绍一下,学习Hadoop开发技术的路线图. Hadoop本身是用java开发的,所以对java的支持性非常好,但也可以使用其他语言. 下面的技术路线侧重数据挖掘方向,因为Python开发效率较高所以我