我有一个带有OLE对象字段的Microsoft Access数据库,其中包含Microsoft Word文档。 我试图找到代码来检索保存在OLE对象中的文件,以便用户可以从我的JavaFx应用程序中的按钮下载它,但我没有成功。
我有以下但我不知道在此之后该怎么做。此外,inputStream
始终为空。
InputStream inputStream = res.getBinaryStream(6);
答案 0 :(得分:4)
关于从数据库中获取二进制数据,您似乎处于正确的轨道上。以下代码适用于Java 7下的UCanAccess 3.0.0,其中[Doc]是Access表中的OLE Object
字段:
String sql = "SELECT Doc FROM OleTest WHERE ID=1";
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql)) {
rs.next();
InputStream inputStream = rs.getBinaryStream(1);
File f = new File("C:/Users/Gord/Desktop/thing.bin");
Files.copy(
inputStream,
f.toPath(),
java.nio.file.StandardCopyOption.REPLACE_EXISTING);
}
现在的问题是该字段是否包含Word文档
如果字段包含原始二进制格式的文档,那么我们可以将文件重命名为.docx并直接在Word中打开它。
但是,在我的情况下,它被存储为“包装”的OLE对象,因为我已经使用Access本身中的“插入对象...”将文档嵌入到表中。因此.docx(Word)文档,原始形式看起来像这样......
...是从数据库中提取出来的“OLE包装器”:
如果我们从数据库中搜索OLE数据,我们可以看到原始二进制数据的开头,在这种情况下偏移量为0xA57:
所以,遗憾的是,我们不能简单地将OLE二进制数据保存到文件中,然后直接在Word中打开该文件,因为它不是有效的Word文件。
删除OLE“包装器”可能很棘手。某些文件格式被设计为忽略文件末尾的无关字节,因此像this answer中描述的那样(只删除OLE包装器的“前部”)可以像图像文件格式一样使用BMP,JPEG等。不幸的是,Word文档对文件末尾的“垃圾”的宽容度要低得多,因此只删除OLE包装器的“前端部分”仍然会导致Word无法打开的文件。