2

我有一个数据提供者向我发送一些应该用 UTF-8 编码的数据。此数据表示以下字节序列:

28 49 4e 54 e2 80 99 4c 29 20  (INT’L) => "(INT’L)"

由于某种原因,当我的 java 程序获取此数据并将其存储在数据库中时,上述序列变为:

28 49 4e 54 19 4c 29 20        (INT.L) => "(INT\u0019L)"

java程序建立在hibernate之上。它首先从提供者获取数据,将其存储在一个实体中,然后将该实体持久保存在数据库(Postgresql)中。

为什么我会丢失字节(e2 80 99变成19)?
我怎样才能避免这种情况?

这是用于将从提供程序获取的数据传输到实体的核心方法:

import java.sql.Clob;

//...

public static String convertStreamToString(Clob clob) throws SQLException {
    if (clob == null) {
        return "";
    }

    BufferedReader br = null;
    StringBuilder result = new StringBuilder();

    try {
        br = new BufferedReader(new InputStreamReader(clob.getAsciiStream(), Charset.forName("UTF-8")));
        String lig;
        int n = 0;
        while ((lig = br.readLine()) != null) {
            if (n > 0) {
                result.append("\n");
            }
            result.append(lig);
            n++;
        }
    } catch (IOException ioe) {
         // Exception handling code ...
    } catch (SQLException sqlex) {
         // Exception handling code ...
    } finally {
        IOUtil.close(br);
    }

    return result.toString();
}

// ...

MyEntity entity = ...
oracle.sql.NCLOB clob = ...
entity.setProperty(convertStreamToString(clob));


@Entity
class MyEntity {
     @Column(name="prop", length=100000)
     private String prop;  

     public void setProperty(String value) {
          this.prop=value;
     }
}
4

2 回答 2

4

您正在使用getAsciiStream()来读取 CLOB 的内容。顾名思义,这种方法只能用于 ASCII;它破坏了所有非 ASCII 字符。

请改用该getCharacterStream方法。

BufferedReader br = null;
StringBuilder result = new StringBuilder();

try {
    br = new BufferedReader(clob.getCharacterStream());
    ....
于 2013-08-16T11:12:13.977 回答
0

我认为 DB 列类型应该支持 UTF-8。在 Oracle 中这是 NVARCHAR,在 Postgresql 中是这样的

create table test (
    utf8fld varchar(50)
);
于 2013-08-16T09:49:37.507 回答