Java中将byte[]转为Blob对象

简介:
准备先把以前写的持久层及表示层框架写完再写loonframework-game包(实际上是想自己业余建站用,用现成的框架太无聊,重复发明轮子的最 大意义就在于解闷……),在2005年时写过一个开头,由于自己没有整理文档,现在拿起来就觉得代码很乱,又懒于写文档,于是把一些心得类的东西整理一 下,用以备忘。

在此持久层框架中,我将持久化过程分为两个松耦合模块,第一模块封装jdbc操作,隐藏Connection及相关事务,处理driver差异后执行标准CRUD并释放资源,于第二模块进行实体映射操作。

但 和Spring JdbcTemplate等jdbc封装略有不同的是,我除了直接将结果集转为List和实体返回外,还引入了一个类似CachedRowSet但非继承 CachedRowSet或ResultSet的结果集cache实体(没有提供诸如CachedRowSet的execute功能,原因大家都知 道……PS:05年我用Hibernate还比较少,现在看来和Hierbante的ScrollableResults接口超级类似,颇感java技术 殊途同归|||)。

但在此类get数据时,由于我将所有ResultSet数据无差别以object方式存储,当object为二进制对象时,为实现blob和clob接口就需要进行数据转换,将二进制对象转为blob或clob实现,为此完成代码如下。

比较hibernate的blobimpl而言(hibernate的blobimpl只有getBinaryStream()实现,因为别的对它也没用……),实现了更多的函数以供调用。 

BlobImpl.java
package  org.loon.framework.dao.lob;

import  java.io.BufferedInputStream;
import  java.io.ByteArrayInputStream;
import  java.io.ByteArrayOutputStream;
import  java.io.IOException;
import  java.io.InputStream;

import  java.io.OutputStream;
import  java.sql.Blob;
import  java.sql.SQLException;

import  org.loon.framework.Loon;
import  org.loon.framework.helper.FileHelper;

/**
 * <p>
 * Title: LoonFramework
 * </p>
 * <p>
 * Description:二进制大对象Blob实现,用于转化二进制对象为blob实例,只提供get部分方法(虽然象征性的写了
 * set实现,但没有对数据库进行操作,只是摆设……).
 * </p>
 * <p>
 * Copyright: Copyright (c) 2007
 * </p>
 * <p>
 * Company: LoonFramework
 * </p>
 * <p>
 * License: 
[url]http://www.apache.org/licenses/LICENSE-2.0[/url]
 * </p>
 * 
 * 
@author chenpeng
 * @email:[email]ceponline@yahoo.com.cn[/email]
 * 
@version 0.1
 
*/

public   class  BlobImpl  implements  Blob  {


    
private byte[] _bytes = new byte[0];

    
private int _length = 0;

    
/**
     * 构造函数,以byte[]构建blob
     * 
     * 
@param bytes
     
*/

    
public BlobImpl(byte[] bytes) {
        init(bytes);
    }


    
/**
     * 构造函数,以InputStream构建blob
     * 
     * 
@param bytes
     
*/

    
public BlobImpl(InputStream input) {
        init(FileHelper.read(input));
    }


    
/**
     * 构造函数,以blob重新构建blob
     * 
     * 
@param bytes
     
*/

    
public BlobImpl(Blob blob) {
        init(blobToBytes(blob));
    }


    
/**
     * 初始化byte[]
     * 
     * 
@param b
     
*/

    
private void init(byte[] bytes) {
        _bytes 
= bytes;
        _length 
= _bytes.length;
    }


    
/**
     * 将blob转为byte[]
     * 
     * 
@param blob
     * 
@return
     
*/

    
private byte[] blobToBytes(Blob blob) {
        BufferedInputStream is 
= null;
        
try {
            is 
= new BufferedInputStream(blob.getBinaryStream());
            
byte[] bytes = new byte[(int) blob.length()];
            
int len = bytes.length;
            
int offset = 0;
            
int read = 0;
            
while (offset < len
                    
&& (read = is.read(bytes, offset, len - offset)) >= 0{
                offset 
+= read;
            }

            
return bytes;
        }
 catch (Exception e) {
            
return null;
        }
 finally {
            
try {
                is.close();
                is 
= null;
            }
 catch (IOException e) {
                
return null;
            }


        }

    }


    
/**
     * 获得blob中数据实际长度
     * 
     * 
@return
     * 
@throws SQLException
     
*/

    
public long length() throws SQLException {
        
return _bytes.length;
    }


    
/**
     * 返回指定长度的byte[]
     * 
     * 
@param pos
     * 
@param len
     * 
@return
     * 
@throws SQLException
     
*/

    
public byte[] getBytes(long pos, int len) throws SQLException {
        
if (pos == 0 && len == length())
            
return _bytes;
        
try {
            
byte[] newbytes = new byte[len];
            System.arraycopy(_bytes, (
int) pos, newbytes, 0, len);
            
return newbytes;
        }
 catch (Exception e) {
            
throw new SQLException("Inoperable scope of this array");
        }

    }


    
/**
     * 返回InputStream
     * 
     * 
@return
     * 
@throws SQLException
     
*/

    
public InputStream getBinaryStream() throws SQLException {
        
return new ByteArrayInputStream(_bytes);
    }


    
/**
     * 获取此byte[]中start的字节位置
     * 
     * 
@param pattern
     * 
@param start
     * 
@return
     * 
@throws SQLException
     
*/

    
public long position(byte[] pattern, long start) throws SQLException {
        start
--;
        
if (start < 0{
            
throw new SQLException("start < 0");
        }

        
if (start >= _length) {
            
throw new SQLException("start >= max length");
        }

        
if (pattern == null{
            
throw new SQLException("pattern == null");
        }

        
if (pattern.length == 0 || _length == 0 || pattern.length > _length) {
            
return -1;
        }

        
int limit = (int) _length - pattern.length;
        
for (int i = (int) start; i <= limit; i++{
            
int p;
            
for (p = 0; p < pattern.length && _bytes[i + p] == pattern[p]; p++{
                
if (p == pattern.length) {
                    
return i + 1;
                }

            }

        }

        
return -1;
    }


    
/**
     * 获取指定的blob中start的字节位置
     * 
     * 
@param pattern
     * 
@param start
     * 
@return
     * 
@throws SQLException
     
*/

    
public long position(Blob pattern, long start) throws SQLException {
        
return position(blobToBytes(pattern), start);
    }


    
/**
     * 不支持操作异常抛出
     * 
     
*/

    
void nonsupport() {
        
throw new UnsupportedOperationException("This method is not supported!");
    }


    
/**
     * 释放Blob对象资源
     * 
     * 
@throws SQLException
     
*/

    
public void free() throws SQLException {
        _bytes 
= new byte[0];
        _length 
= 0;
    }


    
/**
     * 返回指定长度部分的InputStream,并返回InputStream
     * 
     * 
@param pos
     * 
@param len
     * 
@return
     * 
@throws SQLException
     
*/

    
public InputStream getBinaryStream(long pos, long len) throws SQLException {
        
return new ByteArrayInputStream(getBytes(pos, (int) len));
    }


    
/**
     * 以指定指定长度将二进制流写入OutputStream,并返回OutputStream
     * 
     * 
@param pos
     * 
@return
     * 
@throws SQLException
     
*/

    
public OutputStream setBinaryStream(long pos) throws SQLException {
        
// 暂不支持
        nonsupport();
        pos
--;
        
if (pos < 0{
            
throw new SQLException("pos < 0");
        }

        
if (pos > _length) {
            
throw new SQLException("pos > length");
        }

        
// 将byte[]转为ByteArrayInputStream
        ByteArrayInputStream inputStream = new ByteArrayInputStream(_bytes);
        ByteArrayOutputStream os 
= new ByteArrayOutputStream();
        
byte[] bytes = new byte[(int) pos];
        
try {
            bytes 
= new byte[inputStream.available()];
            
int read;
            
while ((read = inputStream.read(bytes)) >= 0{
                os.write(bytes, 
0, read);
            }


        }
 catch (IOException e) {
            e.getStackTrace();
        }


        
// 返回OutputStream
        return (OutputStream) os;
    }


    
/**
     * 设定byte[]
     * 
     * 
@param pos
     * 
@param bytes
     * 
@param offset
     * 
@param size
     * 
@param copy
     * 
@return
     * 
@throws SQLException
     
*/

    
private int setBytes(long pos, byte[] bytes, int offset, int size,
            
boolean copy) throws SQLException {
        
// 暂不支持
        nonsupport();
        pos
--;
        
if (pos < 0{
            
throw new SQLException("pos < 0");
        }

        
if (pos > _length) {
            
throw new SQLException("pos > max length");
        }

        
if (bytes == null{
            
throw new SQLException("bytes == null");
        }

        
if (offset < 0 || offset > bytes.length) {
            
throw new SQLException("offset < 0 || offset > bytes.length");
        }

        
if (size < 0 || pos + size > (long) Integer.MAX_VALUE
                
|| offset + size > bytes.length) {
            
throw new SQLException();
        }

        
// 当copy数据时
        if (copy) {
            _bytes 
= new byte[size];
            System.arraycopy(bytes, offset, _bytes, 
0, size);
        }
 else // 否则直接替换对象
            _bytes = bytes;
        }

        
return _bytes.length;
    }


    
/**
     * 设定指定开始位置byte[]
     * 
     * 
@param pos
     * 
@param bytes
     * 
@return
     * 
@throws SQLException
     
*/

    
public int setBytes(long pos, byte[] bytes) throws SQLException {
        
// 暂不支持
        nonsupport();
        
return setBytes(pos, bytes, 0, bytes.length, true);
    }


    
/**
     * 设定byte[]
     * 
     * 
@param pos
     * 
@param bytes
     * 
@param offset
     * 
@param len
     * 
@return
     * 
@throws SQLException
     
*/

    
public int setBytes(long pos, byte[] bytes, int offset, int len)
            
throws SQLException {
        
// 暂不支持
        nonsupport();
        
return setBytes(pos, bytes, offset, len, true);
    }


    
/**
     * 截取相应部分数据
     * 
     * 
@param len
     * 
@throws SQLException
     
*/

    
public void truncate(long len) throws SQLException {
        
if (len < 0{
            
throw new SQLException("len < 0");
        }

        
if (len > _length) {
            
throw new SQLException("len > max length");
        }

        _length 
= (int) len;
    }


    
public static void main(String[] args) {

        
//获得一个指定文件的blob
        
//PS:天地良心啊,没抄袭hibernate写法,无奈的写一样了,不过比他多实现了点方法……(还特意把函数改名,不然更像|||)……
        Blob blob = Loon.makeBlob("D:\test.txt"); 
        
// 以byte[]获得blob实例
        
//Blob blob = new BlobImpl(bytes);
        try {
            
// getBytes测试
            
// 取出0到blob结束范围的byte[]
            byte[] buffer = blob.getBytes(0, (int) blob.length());
            
// 以gb2312编码将byte[]转为string显示
            System.out.println(new String(buffer, "gb2312"));

            
// getBinaryStream测试
            BufferedInputStream is = new BufferedInputStream(blob
                    .getBinaryStream());
            buffer 
= new byte[(int) blob.length()];
            
int len = buffer.length;
            
int offset = 0;
            
int read = 0;
            
while (offset < len
                    
&& (read = is.read(buffer, offset, len - offset)) >= 0{
                offset 
+= read;
            }

            System.out.println(
new String(buffer, "gb2312"));

            
// getBinaryStream范围取值测试,取0to4的byte[]
            is = new BufferedInputStream(blob.getBinaryStream(04));
            
//将is转为byte[]后转为String显示
            System.out.println(FileHelper.readToString(is, "gb2312"));

        }
 catch (Exception e) {
            e.printStackTrace();
        }


    }


}


本文转自 cping 51CTO博客,原文链接:http://blog.51cto.com/cping1982/130046


相关文章
|
存储 Java 开发工具
【Azure 存储服务】Java Azure Storage SDK V12使用Endpoint连接Blob Service遇见 The Azure Storage endpoint url is malformed
【Azure 存储服务】Java Azure Storage SDK V12使用Endpoint连接Blob Service遇见 The Azure Storage endpoint url is malformed
259 0
|
存储 Java 开发工具
【Azure 存储服务】Azure Blob上传大文件(600MB)出现内存溢出情况(Java SDK)
【Azure 存储服务】Azure Blob上传大文件(600MB)出现内存溢出情况(Java SDK)
377 0
|
存储 Java 开发工具
【Azure Developer】VS Code运行Java 版Azure Storage SDK操作Blob (新建Container, 上传Blob文件,下载及清理)
【Azure Developer】VS Code运行Java 版Azure Storage SDK操作Blob (新建Container, 上传Blob文件,下载及清理)
257 0
|
Java Apache Maven
Java:commons-codec实现byte数组和16进制字符串转换
在上述代码中,`Hex.encodeHexString(bytes)`用于将byte数组转换为16进制字符串,`Hex.decodeHex(hexString)`用于将16进制字符串转换为byte数组。
623 0
|
Java Apache Maven
Java:commons-codec实现byte数组和16进制字符串转换
在上述代码中,`Hex.encodeHexString(bytes)`用于将byte数组转换为16进制字符串,`Hex.decodeHex(hexString)`用于将16进制字符串转换为byte数组。
572 0
|
SQL 关系型数据库 MySQL
PostgreSQL【异常 01】java.io.IOException:Tried to send an out-of-range integer as a 2-byte value 分析+解决
PostgreSQL【异常 01】java.io.IOException:Tried to send an out-of-range integer as a 2-byte value 分析+解决
1252 1
|
Java
java 读取文件 获取byte[]字节 并执行Gzip的压缩和解压
java 读取文件 获取byte[]字节 并执行Gzip的压缩和解压
504 0
|
存储 自然语言处理 Java
Java_9_为何要将_String_的底层实现由_char[]_改成了_byte[]_?
Java_9_为何要将_String_的底层实现由_char[]_改成了_byte[]_?
|
存储 Java 计算机视觉
java 之byte
当涉及到处理数据时,Java 提供了多种数据类型,其中包括 `byte` 类型。在本文中,我们将深入探讨 Java 中的 `byte` 数据类型,了解它的特点、用途以及在编程中的实际应用。
|
Java
Java中 String与基本数据类型,包装类,char[],byte[]之间的转换
Java中 String与基本数据类型,包装类,char[],byte[]之间的转换
474 0

热门文章

最新文章

下一篇
开通oss服务