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:
http://www.apache.org/licenses/LICENSE-2.0
*</p>
*
*
@authorchenpeng
*@email:[email protected]
*
@version0.1
*/

public class BlobImpl implements Blob ... {


privatebyte[]_bytes=newbyte[0];

privateint_length=0;

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

publicBlobImpl(byte[]bytes)...{
init(bytes);
}


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

publicBlobImpl(InputStreaminput)...{
init(FileHelper.read(input));
}


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

publicBlobImpl(Blobblob)...{
init(blobToBytes(blob));
}


/***//**
*初始化byte[]
*
*
@paramb
*/

privatevoidinit(byte[]bytes)...{
_bytes
=bytes;
_length
=_bytes.length;
}


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

privatebyte[]blobToBytes(Blobblob)...{
BufferedInputStreamis
=null;
try...{
is
=newBufferedInputStream(blob.getBinaryStream());
byte[]bytes=newbyte[(int)blob.length()];
intlen=bytes.length;
intoffset=0;
intread=0;
while(offset<len
&&(read=is.read(bytes,offset,len-offset))>=0)...{
offset
+=read;
}

returnbytes;
}
catch(Exceptione)...{
returnnull;
}
finally...{
try...{
is.close();
is
=null;
}
catch(IOExceptione)...{
returnnull;
}


}

}


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

publiclonglength()throwsSQLException...{
return_bytes.length;
}


/***//**
*返回指定长度的byte[]
*
*
@parampos
*
@paramlen
*
@return
*
@throwsSQLException
*/

publicbyte[]getBytes(longpos,intlen)throwsSQLException...{
if(pos==0&&len==length())
return_bytes;
try...{
byte[]newbytes=newbyte[len];
System.arraycopy(_bytes,(
int)pos,newbytes,0,len);
returnnewbytes;
}
catch(Exceptione)...{
thrownewSQLException("Inoperablescopeofthisarray");
}

}


/***//**
*返回InputStream
*
*
@return
*
@throwsSQLException
*/

publicInputStreamgetBinaryStream()throwsSQLException...{
returnnewByteArrayInputStream(_bytes);
}


/***//**
*获取此byte[]中start的字节位置
*
*
@parampattern
*
@paramstart
*
@return
*
@throwsSQLException
*/

publiclongposition(byte[]pattern,longstart)throwsSQLException...{
start
--;
if(start<0)...{
thrownewSQLException("start<0");
}

if(start>=_length)...{
thrownewSQLException("start>=maxlength");
}

if(pattern==null)...{
thrownewSQLException("pattern==null");
}

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

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

}

}

return-1;
}


/***//**
*获取指定的blob中start的字节位置
*
*
@parampattern
*
@paramstart
*
@return
*
@throwsSQLException
*/

publiclongposition(Blobpattern,longstart)throwsSQLException...{
returnposition(blobToBytes(pattern),start);
}


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

voidnonsupport()...{
thrownewUnsupportedOperationException("Thismethodisnotsupported!");
}


/***//**
*释放Blob对象资源
*
*
@throwsSQLException
*/

publicvoidfree()throwsSQLException...{
_bytes
=newbyte[0];
_length
=0;
}


/***//**
*返回指定长度部分的InputStream,并返回InputStream
*
*
@parampos
*
@paramlen
*
@return
*
@throwsSQLException
*/

publicInputStreamgetBinaryStream(longpos,longlen)throwsSQLException...{
returnnewByteArrayInputStream(getBytes(pos,(int)len));
}


/***//**
*以指定指定长度将二进制流写入OutputStream,并返回OutputStream
*
*
@parampos
*
@return
*
@throwsSQLException
*/

publicOutputStreamsetBinaryStream(longpos)throwsSQLException...{
//暂不支持
nonsupport();
pos
--;
if(pos<0)...{
thrownewSQLException("pos<0");
}

if(pos>_length)...{
thrownewSQLException("pos>length");
}

//将byte[]转为ByteArrayInputStream
ByteArrayInputStreaminputStream=newByteArrayInputStream(_bytes);
ByteArrayOutputStreamos
=newByteArrayOutputStream();
byte[]bytes=newbyte[(int)pos];
try...{
bytes
=newbyte[inputStream.available()];
intread;
while((read=inputStream.read(bytes))>=0)...{
os.write(bytes,
0,read);
}


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


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


/***//**
*设定byte[]
*
*
@parampos
*
@parambytes
*
@paramoffset
*
@paramsize
*
@paramcopy
*
@return
*
@throwsSQLException
*/

privateintsetBytes(longpos,byte[]bytes,intoffset,intsize,
booleancopy)throwsSQLException...{
//暂不支持
nonsupport();
pos
--;
if(pos<0)...{
thrownewSQLException("pos<0");
}

if(pos>_length)...{
thrownewSQLException("pos>maxlength");
}

if(bytes==null)...{
thrownewSQLException("bytes==null");
}

if(offset<0||offset>bytes.length)...{
thrownewSQLException("offset<0||offset>bytes.length");
}

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

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

return_bytes.length;
}


/***//**
*设定指定开始位置byte[]
*
*
@parampos
*
@parambytes
*
@return
*
@throwsSQLException
*/

publicintsetBytes(longpos,byte[]bytes)throwsSQLException...{
//暂不支持
nonsupport();
returnsetBytes(pos,bytes,0,bytes.length,true);
}


/***//**
*设定byte[]
*
*
@parampos
*
@parambytes
*
@paramoffset
*
@paramlen
*
@return
*
@throwsSQLException
*/

publicintsetBytes(longpos,byte[]bytes,intoffset,intlen)
throwsSQLException...{
//暂不支持
nonsupport();
returnsetBytes(pos,bytes,offset,len,true);
}


/***//**
*截取相应部分数据
*
*
@paramlen
*
@throwsSQLException
*/

publicvoidtruncate(longlen)throwsSQLException...{
if(len<0)...{
thrownewSQLException("len<0");
}

if(len>_length)...{
thrownewSQLException("len>maxlength");
}

_length
=(int)len;
}


publicstaticvoidmain(String[]args)...{

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

//getBinaryStream测试
BufferedInputStreamis=newBufferedInputStream(blob
.getBinaryStream());
buffer
=newbyte[(int)blob.length()];
intlen=buffer.length;
intoffset=0;
intread=0;
while(offset<len
&&(read=is.read(buffer,offset,len-offset))>=0)...{
offset
+=read;
}

System.out.println(
newString(buffer,"gb2312"));

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

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


}


}

你可能感兴趣的:(byte[])