Hbase的Java API的利用(有关图片等数据的put和get)

      Hbase是针对海量数据而生的,它的原型为bigtable,他可以用来存储各种格式的数据,我们对Hbase的操作常常是在Hbase的shell界面下利用指令对其操作的,但是这远远不能够满足我们的需求,所以,Hbase的Java API就得到了广泛的应用。其中,使用率最高的当属Put和Get,也就是在表中添加数据,和从表中查询数据。如果我们向Hbase中插入的数据是字符串的类型,那么我们直接通过Hbase shell的put指令即可,但是,如果是针对图片、视频等非结构化的数据该怎么办呢?在这里我以添加一张图片为例子,我用到的表名为talk,里面就一个列簇为file。

     我们先说如何添加一张图片到表的列簇中,我们都知道数据是以二进制的行书存储在HDFS上的,所以我们最主要的是先将图片转换成byte[ ]格式的数据,然后将其添加到Hbase中。代码如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;

public class Put_data {
	
	public static Connection connection;
	public static Configuration configuration;
	//参数配置,主要用来到zookeeper中寻找regionServer的信息
	public static void init(){  
        configuration = HBaseConfiguration.create();  
        configuration.set("hbase.zookeeper.quorum", "hdfsvm001.hogpu.cc,hdfsvm002.hogpu.cc");  
        configuration.set("hbase.zookeeper.property.clientPort","2181");  
        configuration.set("zookeeper.znode.parent","/hbase-unsecure");  
  
        try {  
            connection = ConnectionFactory.createConnection(configuration);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
	
	public static void main(String[] args) throws IOException {
		putRows();	
	}
	
	public static void putRows() throws IOException{
               init();
                //得到表名为talk的表
               Table table = connection.getTable(TableName.valueOf("talk"));
                int i = 1;
                //读取图片
               File file = new File("/home/laipeng.han/oozie-result.png");
                //这里为什么要设置为40961,因为图片的大小是40kb
               byte[] img = new byte[40961];
                //利用输入流将图片转换成二进制的形式
               InputStream a = null;
		a = new FileInputStream(file);
		a.read(img);
                //创建put对象,括号中的为插入的行键
               Put put = new Put(Bytes.toBytes("row"+i));
                //将图片插入指定列中,参数为(列簇,列,值)
               put.addColumn(Bytes.toBytes("file"), null, img);
		table.put(put);
		table.close();
		System.out.println("done put rows");
	}

}
      好,我们现在已经将图片插入到制定的列中了,如果我们想get这张图片该怎么办呢?很明显Hbase shell并不能满足我们的需求,所以,我们用到了Get api。其中,重点就是我们get到底的结果是一个二进制的结果,我们需要将其转化成图片的形式,代码如下:

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;


public class Get_data {
	
	public static Connection connection;
	public static Configuration configuration;
	
	public static void init(){  
        configuration = HBaseConfiguration.create();  
        configuration.set("hbase.zookeeper.quorum", "hdfsvm001.hogpu.cc,hdfsvm002.hogpu.cc");  
        configuration.set("hbase.zookeeper.property.clientPort","2181");  
        configuration.set("zookeeper.znode.parent","/hbase-unsecure");  
  
        try {  
            connection = ConnectionFactory.createConnection(configuration);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		getData();

	}
	
	public static void getData() throws IOException{
		init();
                //首先我们需要先定位到表,到哪一行,如果想多行读取的话可以用scan,单行这里用的是get
               Table table = connection.getTable(TableName.valueOf("talk"));
		String rowid = "row1";
                //创建Get对象,并将结果读出到result中
               Get get = new Get(Bytes.toBytes(rowid));
		get.addFamily(Bytes.toBytes("file"));
		Result result = table.get(get);
		show(result);
		table.close();
	}
	//将读出的二进制结果转换成图片文件
	public static void show(Result result) throws IOException{
		byte[] image = new byte[40961];
		Cell[] cells = result.rawCells();
                //在这里我们先将二进制格式的value值取出
               for(Cell cell:cells){
		     image = CellUtil.cloneValue(cell);
		}
                //利用文件的输入输出流的将其转换成图片文件
               if(image != null && image.length > 0){
			InputStream in = new ByteArrayInputStream(image);
			File img_file = new File("/home/laipeng.han/data/", "oozie.png");
			FileOutputStream out = new FileOutputStream(img_file);
			byte[] b = new byte[40961];
			int read = 0;
			while((read = in.read(b)) != -1){
				out.write(b, 0, read);
			}
			out.flush();
			out.close();
			in.close();
		}
	}

}
注:代码经过测试,大家只需要修改路径即可跑通,代码写的很不通用,很多参数都是可以从命令行传进来的,希望大家给予指点与改进。

你可能感兴趣的:(Hbase)