前一阵由于工作中需要,从ORACLE数据库中读取包含ole信息的字段。
在access中我们存储图片信息所用到的类型是OLE.要显示图片我们需要使用stream,这就需要知道唯一标识图像的文件头.
所有的图片文件(格式)都有用来唯一的标识图像的文件头。JPG图片文件以所谓的SOI标记开始,该标记的十六进制值是$FFD8。
MS Access把连接的OLE对象的路径作为对象定义的一部分存储在OLE对象字段中。因为OLE对象的存储定义没有被文档化(!?这直接来自于MS),所以没有办法知道真正的图像数据被写之前能得到什么。
分两个部分考虑这个问题。第一:我们需要找到'FFD8'并从那儿开始读取图像。第二:'FFD8'不可能总在文件的同一个位置。结论:我们需要一个函数,返回Access数据库中存储为OLE对象的JPG文件的SOI标记的位置。
Private Sub Command2_Click()
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
conn.ConnectionString = "DSN=photo;uid=sa;pwd=;"
conn.ConnectionTimeout = 30
conn.Open
rs.Open "select * from t_Photo order by pid", conn, adOpenStatic, adLockReadOnly, adCmdText
Dim index As String
For t = 0 To Val(rs.RecordCount) - 1
If (t > 2) Then
index = Trim(rs.Fields("pid").Value)
Dim size, i, j
'要输出字段的总字节数
size = rs("Picture1").ActualSize
'循环找到 SOI marker 的位置
For i = 1 To size
If AscB(MidB(rs("Picture1"), i, 1)) = &HFF And AscB(MidB(rs("Picture1"), i + 1, 1)) = &HD8 Then
Exit For
End If
Next
Debug.Print "i==========" & i
Dim picsize As Long
picsize = rs("Picture1").ActualSize
Dim iStm As New ADODB.Stream
Set iStm = New ADODB.Stream
With iStm
.Mode = adModeReadWrite
.Type = adTypeBinary
.Open
rs("Picture1").GetChunk (i - 1)
.Write rs("Picture1").GetChunk(picsize - i + 1)
End With
iStm.SaveToFile App.Path & "/cc" & t & ".jpg"
Picture1.Picture = LoadPicture(App.Path & "/cc" & t & ".jpg")
End If
rs.MoveNext
Combo1.AddItem index
Next t
rs.Close
End Sub
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection("jdbc:odbc:photo","sa","");
Statement sql = con.createStatement(); //创建Statement对象
ResultSet rs = sql.executeQuery("select * from t_photo");
while (rs.next()) //输出被查询的情况
{
String pid = rs.getString("pid");
byte[] pic = rs.getBytes("picture1");
FileOutputStream fo = new FileOutputStream("c:\\2.bmp");
//FileInputStream fi = rs.getCharacterStream("picture1");
int start = 166;
for(int i=start; i
fo.write(pic[i]);
}
fo.close();
System.out.println(pid);
}
}catch(Exception e){
System.out.println(e);
}