代码之家  ›  专栏  ›  技术社区  ›  ZioByte

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

  •  2
  • ZioByte  · 技术社区  · 7 年前

    我有一个很大的房间 .mdb access数据库我想转换成SQLite3在Linux下使用它。

    我无法转让任何一项权利 BLOB

    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
    

    我做错了什么?

    更新: BookCAT 由于历史原因)我发现 AccessConverter

    • 在我的数据库中,一些列被命名为“Index”,这是SQLite(和其他列,但显然不是MS Access)的保留字;插入过滤器“索引”->Idx”。
    • switch (type) { case xxx: ... 将各种MS访问类型转换为更传统的SQLite3类型;在 default: 我发现的标签(正如@ErikvonAsmuth正确猜测的)有未处理的标签 OLE 类型。我不知道如何处理这些问题。

    在程序(BookCAT)中,这些字段包含两种数据:

    • 图像
    • 格式化文本

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

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

    我能做些什么来检索 对象链接和嵌入 可用格式的数据?

    AccessConverter ucanaccess ,它直接使用底层 com.healthmarketscience.jackcess 而是lib。

    注2: 看来 BookCAT

    2 回复  |  直到 7 年前
        1
  •  2
  •   ZioByte    7 年前

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

    在这种情况下,jackcess返回一个 Enum OleBlob.ContentType.UNKNOWN 在这种情况下,它将拒绝访问BLOB内容( OleBlob.content.getBytes() null

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

    为什么在这种情况下,, ucanaccess 返回一个无效值,而不是失败,这超出了我的能力范围(可能我应该提交一个bug报告;欢迎评论)。

    图像数据是纯jpeg格式的文件,而“格式化文本”似乎是某种自定义的Delphi序列化 TRichText

    使用 jackcess 我能够检索到我需要的数据。

        2
  •  1
  •   Gord Thompson    7 年前

    有了UCanAccess,您需要使用 ResultSet#getBlob

    String q = "SELECT * FROM PersonImage";
    ps = conn.prepareStatement(q);
    rs = ps.executeQuery();
    while (rs.next()) {
        java.sql.Blob image = rs.getBlob("Image");
        String fn = String.format("C:/Users/Gord/Pictures/i%05d.%d.jpg", rs.getInt("PersonId"), rs.getInt("Index"));
        try (FileOutputStream fos = new FileOutputStream(fn)) {
                fos.write(image.getBytes(1, (int) image.length()));
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
                e.printStackTrace();
        }
    }
    
    推荐文章