首页 > 代码库 > 基于mapfile的小文件存储方案

基于mapfile的小文件存储方案

1.采用mapfile存储小文件,会自动创建两个sequenceFile文件:data和index。数据存储在data中,index存储data中存储的文件的key(排好序的)。这样可以实现小文件的合并存储,并且实现按key的快速索引。

2.代码:

文件存储:

/**
     * 将指定的文件写入文件系统,指定次数
     * @param p    写入路径
     * @param image    写入文件内容
     * @param count    写入数量
     * @throws IOException
     */
    @Test
    public void MapFileWriter(FileSystem fs,Path p, byte[] image, int count) throws IOException {

        IntWritable key = new IntWritable();
        Text value = http://www.mamicode.com/new Text((byte[]) image);

        MapFile.Writer writer = null;
        Option optKey = MapFile.Writer.keyClass(key.getClass());
        Option optVal = MapFile.Writer.valueClass(value.getClass());

        try {
            writer = new MapFile.Writer(fs.getConf(), p, optKey, optVal);
            long time = System.currentTimeMillis();
            for (int i = 0; i < count; i++) {
                key.set(i);
                writer.append(key, value);
            }
            System.out.println("写入mapfile耗时: " + (System.currentTimeMillis() - time)+" ms");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e);
        } finally {
            IOUtils.closeStream(writer);
        }
    }

/**
     * 从mapfile读取文件,讲读取到的数据写入指定路径
     * @param p mapfile路径
     * @param key 读取文件key
     * @param path 读取文件写入路径
     * @return
     * @throws IOException
     */
    @Test
    public byte[] MapFileReader(FileSystem fs,Path p,IntWritable key, String path) throws IOException {

        MapFile.Reader reader = new MapFile.Reader(p, fs.getConf());
        Text value = http://www.mamicode.com/new Text();
        long time = System.currentTimeMillis();
        reader.get(key, value);
        System.out.println("读取耗时: "+ (System.currentTimeMillis()-time)+ " ms");
        if (value != null) {
            FileWriter(path, value.copyBytes());            
        }else
            logger.error("can not find key :" + key);
        reader.close();
        return value.copyBytes();
    }

3.测试用例

@Before
    public void setUp(){
        System.out.println("=======@before=======");
        mapfile = new mapFileUtil();
        p = new Path("/test5/test.map");
        fs = hdfsInit.getFileSystem();
        inpath = "D://3345400.jpg";
        outpath = "D://image4//test51.jpg";
    }
    
    @After
    public void writerDone(){
        System.out.println("=======@write done=======");
    }
    @After
    public void readerDone(){
        System.out.println("=======@read done=======");
    }
    
    @Test
    public void testWriter() throws IOException{
        mapfile.MapFileWriter(fs,p,mapfile.FileReader(inpath),5);
    }
    
    @Test
    public void testReader() throws IOException{
        byte[] file = mapfile.MapFileReader(fs,p,new IntWritable(3),outpath);
        Assert.assertEquals(Bytes.toString(file), Bytes.toString(mapfile.FileReader(inpath)));
    }

基于mapfile的小文件存储方案