Java UCanAccess似乎无法使用getBytes()读取OLE对象列

Java UCanAccess似乎无法使用getBytes()读取OLE对象列,java,ms-access,jdbc,ucanaccess,jackcess,Java,Ms Access,Jdbc,Ucanaccess,Jackcess,我有一个相当大的.mdb access数据库,我想转换成SQLite3在Linux下使用它 我无法传输任何主要包含我的图像的斑点。 以下是一个示例测试程序: import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.s

我有一个相当大的.mdb access数据库,我想转换成SQLite3在Linux下使用它

我无法传输任何主要包含我的图像的斑点。 以下是一个示例测试程序:

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class prova {
        public static void main(String[] args) {
                String url = "jdbc:ucanaccess://data/BookDB-201810.mdb";
                try {
                        Connection c = DriverManager.getConnection(url);
                        PreparedStatement ps;
                        ResultSet rs;
                        String q = "SELECT * FROM PersonImage";
                        ps = c.prepareStatement(q);
                        rs = ps.executeQuery();
                        while (rs.next()) {
                                byte[] i = rs.getBytes("Image");
                                String fn = String.format("data/img/i%05d.%d.jpg", rs.getInt("PersonId"), rs.getInt("Index"));
                                try (FileOutputStream fos = new FileOutputStream(fn)) {
                                        fos.write(i);
                                } catch (FileNotFoundException e) {
                                        e.printStackTrace();
                                } catch (IOException e) {
                                        e.printStackTrace();
                                }
                        }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
        }
}
程序运行时没有错误,但生成的文件肯定不是图像:

$ ls -l i00072.1.jpg 
-rw-r--r-- 1 mcon mcon 369 Nov 23 11:38 i00072.1.jpg
$ file i00072.1.jpg 
i00072.1.jpg: Java serialization data, version 5
看着他们,我发现:

....sr..net.ucanaccess.jdbc.BlobKey...........L.
columnNamet..Ljava/lang/String;L..keyt..Ljava/util/HashMap;L.   tableNameq.~..xpt..Imagesr..java.util.HashMap......`....F.
loadFactorI.    thresholdxp?@......w.........t..PersonIDsr..java.lang.Integer.⠤...8...I..valuexr..java.lang.Number...........xp...
Ht..Indexsr..java.lang.ShorthM7.4`.R...S..valuexq.~.  ..xt..PersonImage
我做错了什么

更新: 由于历史原因,我的目标是使用过时的程序将网络上维护的图书数据库转换为.mdb,我发现这似乎符合要求;不幸的是,这基本上有两个问题:

在我的数据库中,有些列被命名为Index,这是SQLite和其他列的保留字,但显然不是MS Access的保留字;通过插入过滤器索引->Idx,可以轻松修复此问题。 有一个转换开关类型{case xxx:…将各种MS访问类型转换为更传统的SQLite3类型;在默认值上断点:我发现为@ErikvonAsmuth的标签正确猜测存在未处理的OLE类型。我不知道如何处理这些类型。 在程序BookCAT中,这些字段包含两种数据:

图像 格式化文本 后者不那么重要,因为总是有一个重复的纯文本版本。检索格式化版本也不错,但是

不过,我真的希望能够提取图像

在图像数据中,有一个相伴的ImageType列总是设置为2,如果我没有弄错的话,这意味着它们应该是.jpeg图像

如何以可用格式检索OLE数据

注意:AccessConverter不使用ucanaccess,而是直接使用底层的com.healthmarketscience.jackcess库


注2:BookCAT似乎是使用Delphi构建的,如果相关的话。

事实证明,在我的特定情况下,所有OLE字段实际上都是BLOB,无法识别为OLE2对象

在这种情况下,JackAccess返回枚举OleBlob.ContentType.UNKNOWN类型,在这种情况下,它将拒绝访问BLOB内容OleBlob.content.getBytes返回null

为了访问存储的数据,必须直接使用Column.getBytesname完全绕过OLE子系统

为什么在这种情况下,ucanaccess返回一个无效的值,而不是失败,我无法理解,我可能应该提交一个bug报告;欢迎评论

图像数据是纯jpeg格式的文件,而格式化文本似乎是Delphi TRichText小部件的自定义序列化,我不知道如何解析,但这是另一个问题


使用jackcess Column.getBytesname,我能够检索到所需的数据。

使用UCanAccess,您需要使用resultSetBlob:

字符串q=从PersonImage中选择*; ps=连接准备状态Q; rs=ps.executeQuery; 而rs.next{ java.sql.Blob image=rs.getBlobImage; String fn=String.formatC:/Users/Gord/Pictures/i%05d.%d.jpg、rs.getIntPersonId、rs.getIntIndex; 尝试FileOutputStream fos=新FileOutputStreamfn{ fos.writeimage.getBytes1,int image.length; }捕获文件NotFounde异常{ e、 打印跟踪; }捕捉异常{ e、 打印跟踪; } }
Access中没有VARBINARY。有OLE对象,但它们有多种类型,有些只是包含一个文件作为二进制数据,有些包含特定的头,还有一些压缩文件并将多个文件放在一行中。除非您确切指定要导入的内容,否则我们可能无法帮助您。@ErikvonAsmuth:就在几分钟前,我发现你是绝对正确的。我将更新问题以反映我的发现,并完善问题简短摘要:这些字段包含图像或格式化文本。