java - 通过 Java 插入图像时 Postgres 编码 "UTF8"错误

标签 java sql database postgresql image

我正在将 jpeg 图像插入到我的 UTF-8 编码的 Postgres 数据库中的 bytea 列中。我正在使用准备好的 sql 语句来插入图像。在语句中,我在 Java 中创建了一个 jpeg 图像的文件对象,然后将其作为 FileInputStream 传递给 setBinaryStream 方法。但是,一旦执行语句,我的 Java 应用程序就会时不时地抛出异常,指出:

“错误:编码“UTF8”的无效字节序列:0x84”

这种情况发生在少数几张奇怪的图片上。这些图像是从先前的一组图像中提取的,所有先前的图像都插入得很好,只有少数提取的图像似乎会导致错误。那么我该如何解决这样的问题呢?可以以某种方式将字节流编码为 UTF-8 吗?还是数据库有问题?

顺便说一句,如果我用新图像替换提取的图像并将它们另存为 jpeg,则会发生相同的错误。感谢您的帮助!

代码如下...

缺少一些代码,否则这会很长,但基本上我对路径和目录名称进行了一些检查,以确保它们符合文件系统规则。这是在遍历所有子目录并添加所有 这些子目录中的 jpeg 文件。然后我转到下一个目录,其中包含带有图像的子目录,直到那里没有图像。我还没有添加 try-catches 和日志记录部分。

String imgStr = image.toString();
int age = getAgeFromDir(imgStr);
String gender = getSexFromDir(imgStr);
String table = "";
switch(validIdx){
    case 0: table = "carpals";
        break;
    case 1: table = "d_phalanges";
        break;
    case 2: table = "p_phalanges";
        break;
    case 3: table = "i_phalanges";
        break;
    case 4: table = "epiphyses";
        break;
    case 5: table = "sesamoids";
        break;
    case 6: table = "metacarpals ";
        break;
}

    PreparedStatement ps = con.prepareCall("INSERT INTO " + table +
            " VALUES( (SELECT hands.hand_id FROM hands WHERE hands.age = " + age + " AND hands.gender = '" + gender + "' AND hands.location = '" + path + directory + imageNames[i] + "' )," +
            " (SELECT COUNT(" + table + ".location) FROM " + table + " ), " +
            " ?, ? )"   );

        //go through each sub-directory which contains jpeg images and add them to
        //the database
        File sublist = new File(image + "\\" + subdir[j]);
        String[] files = sublist.list();
        String[] pics = sublist.list(new JpegFilter());

        if(files.length > pics.length){
            //WRITE TO LOG
            //WARNING UNEXPECTED FILES OR DIRECTORIES FOUND IN....
        }

            for(int r = 0; r < pics.length; r++ ){

                    String location = image + "\\" + subdir[j] + "\\" + pics[r];
                    System.out.println(i + "\t" + r + " location : " + location);

                    File f = new File(location);
                    FileInputStream pic = new FileInputStream(f);


                    if(f.isFile()){
                    ps.setString(2, location);
                    ps.setBinaryStream(1, pic, (int)f.length());
                    ps.execute();
                    pic.close();
                    }
            }
    ps.close();

抛出的 SQLException 如下所示,它是在 ps.execute() 处抛出的:

线程“main”中的异常 org.postgresql.util.PSQLException:错误:编码“UTF8”的字节序列无效:0x84 在 org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1608) 在 org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1343) 在 org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:194) 在 org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451) 在 org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:350) 在 org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:343) 在 nuffielddb.HandDB.addExtractedImages(HandDB.java:406) 在 nuffielddb.Main.main(Main.java:37) Java 结果:1

最佳答案

嗯,0x84 不是有效的 utf8 字符:

=> perl -e 'print "\x84"' | iconv -f utf8 -t utf8
iconv: illegal input sequence at position 0

通常 - bytea 可以处理任何字节,但 INSERT 语句是文本字符串,因此必须符合客户端的编码!

插入数据的简单方法:

  1. 将应用程序中的数据编码为 Base64 格式(还有其他选项,但我最容易展示这个)
  2. 插入:INSERT INTO q (x) VALUES (decode(?, 'base64'))

Perl 示例(抱歉,我不会写 Java):

#!/usr/bin/perl
use MIME::Base64;
use DBI;

my $dbh = DBI->connect( "dbi:Pg:dbname=depesz;port=5840", "depesz" );
my $blob = "\x84";
my $encoded = encode_base64( $blob );
$dbh->do("INSERT INTO q (x) VALUES (decode(?, 'base64'))", undef, $encoded );

q 表是:

      Table "public.q"
 Column | Type  | Modifiers
--------+-------+-----------
 x      | bytea |

数据(插入后)如下所示:

# select x, octet_length(x) from q;
  x   | octet_length
------+--------------
 \x84 |            1
(1 row)

关于java - 通过 Java 插入图像时 Postgres 编码 "UTF8"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1266707/

相关文章:

java - 由 : org. springframework.beans.factory.NoSuchBeanDefinitionException 引起:Spring 5 中没有符合类型的 bean

java - 在列中按两次排序

php - 每行返回多行(在 Zend Framework 中)

sql - SQL order by子句中的自定义排序?

database - 您如何将元数据置于版本控制之下?

java - Spring Boot maven 插件找不到主类,无法执行 java

java - 如何获取ezvcard中 'encoded'照片数据?

html - 加入游戏框架

php - 我无法在 PHPmyadmin XAMPP 中设置外键

javascript - 如何在 MySQL 插入语句中包含 JavaScript 变量值