如何读取和存储Access数据库中的OLE对象
分类: 代码, 笔记 | 标签: Access, ole, 数据库 | 日期:2008-09-28 | 1 views
隐/显
你可能对这些也感兴趣
在如何读取Access中OLE对象字段中的图片一文中,我们知道了存储于OLE对象中的图片的格式。其实,除了微软的Office文档之外,其余所有的文档在Access中手动插入的时候都会自动打包。下面就是这种包的格式。
区块1存储内容为单字节的ASCII编码。内容形如”Package”或者是”Document”
区块2存储内容同上。若区块1为”Package”则与之相同,若区块1为”Document”则区块2为可能为”Word.Document.X” 其中X为Word版本号。若区块1为”工作表”,则区块2可能为”Excel.Sheet.X” 其中X为Excel版本号。
区块3的内容基本上与区块2相同。
其他的图中非常详细了。
&1存储的数据为区块7的长度。
&2存储的数据为区块8的长度。
&3存储的数据为区块9的长度。
其余为??的数据块,还摸不清规律,占用一个比特。不完整的今后补充。
2008年10月5日 @ 12:34
附上读取OLE对象中数据的代码,语言为VB.net
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | Public Function ReadInnerFile(ByVal bytes() As Byte, Optional ByRef Filename As String = Nothing, Optional ByRef FullName As String = Nothing, Optional ByRef TempPath As String = Nothing) As Byte() If bytes(16) = 255 AndAlso bytes(17) = 255 AndAlso bytes(18) = 255 AndAlso bytes(19) = 255 Then Else Return bytes End If Dim i As Int16 = 20, InnerType As String = "" While bytes(i) <> 0 InnerType += Chr(bytes(i)) i += 1 End While i += 1 Dim TypeDetail As String = "" While bytes(i) <> 0 TypeDetail += Chr(bytes(i)) i += 1 End While i += 13 Dim futherMore As String = "" While bytes(i) <> 0 futherMore += Chr(bytes(i)) i += 1 End While i += 9 Dim size As Integer = 0 Dim j As Integer For j = 0 To 3 size += bytes(i + j) * Math.Pow(256, j) Next Dim fs() As Byte = {} If InnerType <> "Package" Then Filename = "temp." If futherMore.Contains("Word") Then If futherMore.Split(".")(2) = "12" Then Filename += "docx" Else Filename += "doc" End If ElseIf futherMore.Contains("Excel") Then If futherMore.Split(".")(2) = "12" Then Filename += "xlsx" Else Filename += "xls" End If ElseIf futherMore.Contains("PowerPoint") Then If futherMore.Split(".")(2) = "12" Then Filename += "pptx" Else Filename += "ppt" End If ElseIf futherMore.Contains("Access") Then If futherMore.Split(".")(2) = "12" Then Filename += "accdb" Else Filename += "mdb" End If End If Array.Resize(fs, size) For j = i + 4 To i + 3 + size fs(j - i - 4) = bytes(j) Next Return fs End If i += 6 Filename = "" While bytes(i) <> 0 Filename += Chr(bytes(i)) i += 1 End While i += 1 FullName = "" While bytes(i) <> 0 FullName += Chr(bytes(i)) i += 1 End While i += 9 TempPath = "" While bytes(i) <> 0 TempPath += Chr(bytes(i)) i += 1 End While i += 1 size = 0 For j = 0 To 3 size += bytes(i + j) * Math.Pow(256, j) Next Array.Resize(fs, size) For j = i + 4 To i + 3 + size fs(j - i - 4) = bytes(j) Next Return fs End Function |
有3人发表了评论 ↓发表评论↓


您有继续研究这个问题吗?MS对这个ole对象字段的封装好像没有解释。较早的资料曾提到***header,但都已过时
类似的,Access中手工插入的OLE对象貌似与用代码插入的OLE对象不一样,同一份“.doc”文件用手工插入时名称显示为“microsoft 97-2003 文档”,而代码插入时则是“长二进制文件”!
当手工插入OLE对象时Access会自动添加一些附加的信息,那请问该如何才能通过代码读取该类对象???
[回复]
lx 回复:
二月 3rd, 2012 at 9:21 下午
@峰高的发光, 事实上,以后都没有再研究这个问题了. 手工插入的对象可以自己通过查看结构来得知,就像我枚举的几类文件一样: office系列文档都基本类似, 而图片文件就更加容易读取了.全部代码都在上面了. 至于什么时候是二进制什么时候是扩展的,这需要程序智能判断.使用if就可以
[回复]
峰高的发光 @ 2012年02月3日
网上大多是二进制数据的例子。在Access中手工插入的OLE对象,点击就可以按原来的文件类型打开。ms真是有些糟糕。越来越复杂
[回复]
峰高的发光 @ 2012年02月3日