1、创建一个测试的CF
create Column family ImagesFile with comparator=UTF8Type and default_validation_class=UTF8Type and key_validation_class=UTF8Type and column_metadata= [ {column_name: ImagesFileId , validation_class: UTF8Type,index_type: KEYS}, {column_name: FileName, validation_class: UTF8Type}, {column_name: FileByteDatas, validation_class: UTF8Type} ]; |
2、服务端代码如下:
package com.reach.leekexi.cassandra.hecter;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
public class ImagesCassandraClient {
public static String hosts = "192.168.1.20:9160";
public static String clusterName = "Test Cluster";
public static String keyspaceName = "CasImage";
public static String columnFamily = "ImagesFile";
@SuppressWarnings({ "rawtypes" })
public static void main(String[] args) {
// 参数装载
CassandraParas ps = new CassandraParas();
ps.setHosts(hosts); // 注解数据
ps.setClusterName(clusterName);// 群集名称
ps.setKeyspaceName(keyspaceName);// 键空间
ps.setColumnFamily(columnFamily);// 列族
// cassandra客户端API接口实例
CassandraClient cc = new CassandraClient(ps);
boolean inf = false;// 插入标记
String key = "1";// 插入的Key
// 测试多个字段插入和读取
String[] columnNames = { "ImagesFileId", "FileName" };
String[] columnValues = { "1", "http://avatar.csdn.net/3/1/8/3_jemlee2002.jpg" };
inf = cc.insertMultiColumn(key, columnNames, columnValues);
if (inf)// 如果插入成功则测试打印出来
{
Map map = new HashMap();
map = cc.getMultiColumn(key, columnNames);
for (int i = 0; i < map.size(); i++)
System.out.println(columnNames[i] + " : "
+ map.get(columnNames[i]));
} else {
System.out.println("操作数据失败,CF=" + columnFamily);
}
//把图片存储到Cassandra数据库
String columnName = "FileByteDatas";
String columnValue = parserFileNet("http://avatar.csdn.net/3/1/8/3_jemlee2002.jpg","jpg");
inf = cc.insertOneColumn(key, columnName, columnValue);
if (inf) {
System.out.println(cc.getOneColumn(key, columnName));
}
//把数据库的种的图片数据还原成图片
//如果在C盘下看到了和http://avatar.csdn.net/3/1/8/3_jemlee2002.jpg一个样的图片数据,证明数据处理成功。
columnValue = cc.getOneColumn(key, columnName);
String localpath = "c:\\3_jemlee2002.jpg";
String type = "jpg";
boolean ref = revertImage(columnValue,localpath,type);
if(ref)
System.out.println("创建文件:" + localpath + " 成功.");
else
System.out.println("创建文件:" + localpath + " 失败.");
}
/**
* 网络文件存储
* @param URLName 网络图片地址
* @param type 图片类型
* @return String 转换结果
* @throws
*/
public static String parserFileNet(String URLName,String type) {
String res = null;
try {
int HttpResult = 0; // 服务器返回的状态
URL url = new URL(URLName); // 创建URL
URLConnection urlconn = url.openConnection(); // 试图连接并取得返回状态码
urlconn.connect();
HttpURLConnection httpconn = (HttpURLConnection) urlconn;
HttpResult = httpconn.getResponseCode();
System.out.println(HttpResult);
if (HttpResult != HttpURLConnection.HTTP_OK) // 不等于HTTP_OK则连接不成功
System.out.print("fail");
else {
BufferedInputStream bis = new BufferedInputStream(urlconn.getInputStream());
BufferedImage bm = ImageIO.read(bis);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(bm, type, bos);
bos.flush();
byte[] data = bos.toByteArray();
res = byte2hex(data);
bos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
/**
* 本地文件存储
* @param filepath 本地文件路径
* @return String 转换结果
*/
public static String parserFileLocal(String filepath) {
File file = new File(filepath);
byte[] bfile = new byte[10240];
String filestr = "";
try {
InputStream a = new FileInputStream(file);
a.read(bfile);
filestr = byte2hex(bfile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return filestr;
}
/**
* 把Cassandra数据库中的图片数据还原成图片
* @param data 生成图片的二进制字符串
* @param fileName 图片名称(完整路径)
* @param type 图片类型
* @return
*/
public static boolean revertImage(String data, String fileName,String type) {
BufferedImage image = new BufferedImage(300, 300,BufferedImage.TYPE_BYTE_BINARY);
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
boolean rf = false;
try {
ImageIO.write(image, type, byteOutputStream);
byte[] bytes = hex2byte(data);
RandomAccessFile file = new RandomAccessFile(fileName, "rw");
file.write(bytes);
file.close();
rf = true;
} catch (IOException e) {
rf = false;
e.printStackTrace();
}
return rf;
}
/**
* 二进制转字符串
* @param
* @return
*/
public static String byte2hex(byte[] b)
{
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1)
hs = hs + "0" + stmp;
else
hs = hs + stmp;
}
return hs;
}
/**
* 字符串转二进制
* @param str
* @return
*/
public static byte[] hex2byte(String str) {
if (str == null)
return null;
str = str.trim();
int len = str.length();
if (len == 0 || len % 2 == 1)
return null;
byte[] b = new byte[len / 2];
try {
for (int i = 0; i < str.length(); i += 2) {
b[i / 2] = (byte) Integer
.decode("0x" + str.substring(i, i + 2)).intValue();
}
return b;
} catch (Exception e) {
return null;
}
}
}
3、总结
以上代码高效的实现图片(含网络上的和本地的)存储到Cassandra数据的过程。特别提出,该方案中,中间并不需要中间暂存图片到本地,而是直接从http协议上获取图片流数据,这样极大的提高图片的处理速度。