1

我有一个 postgres 9.2 数据库,它的编码是 UTF-8。我有一个应用程序(用 java 编写)来更新这个数据库,读取 .sql 文件并在数据库中执行它们。但我发现了一个问题:在其中一个 .sql 文件中,我有以下说明:

insert into usuario(nome)
values('Usuário Padrão');

执行此操作后,当我转到表数据时,插入的是这样的:"Usuário Padrão"

如果我直接从 pgAdmin 执行此命令,它会正确创建。所以我不知道这是数据库中的问题,还是执行脚本的程序中的问题。

- -编辑 - -

这是我如何获得 JDBC 连接:

public static Connection getConnection() throws SQLException{
    Connection connection;
    String url="jdbc:postgresql://"+servidor+":"+porta+"/"+nomeBanco;
    Properties props = new Properties();  
    props.put("user", usuario);  
    props.put("password", senha);
    connection=DriverManager.getConnection(url,props);
    connection.setAutoCommit(false);
    return connection;
}

这是我用来读取文件的代码,但这看起来是正确的,因为如果我打印从文件中读取的字符串,它会显示正确的字符串。

public static String lerArquivo(File arquivo){
    StringBuilder conteudo=new StringBuilder();
    BufferedReader br = null;
    try {
        br=new BufferedReader(new FileReader(arquivo));
        String linha;
        while((linha=br.readLine())!=null){
            conteudo.append(linha).append("\n");
        }
    } catch (IOException e) {
        FrameErroBasico f=new FrameErroBasico(null, true);
        f.setText("Erro ao ler arquivo.",e);
        f.setVisible(true);
    }finally{
        try{br.close();}catch(Exception e){}
    }
    return conteudo.toString();
}
4

3 回答 3

3

这很可能是有问题的行:

    br=new BufferedReader(new InputStreamReader(new FileInputStream(arquivo), "UTF-8"));

(看起来我的水晶球还在工作!)

于 2013-07-24T16:11:23.327 回答
1

可以肯定的是,我需要查看读取 SQL 文件的代码,但是(正如 jtahlborn 所指出的)我会说您正在使用不同于它真正具有的编码的编码读取文件。

PgJDBC 在 Java 端使用 Unicode,并通过始终以 utf-8 与服务器通信来处理客户端/服务器编码差异,让服务器执行任何所需的编码转换。因此,除非您client_encoding通过 PgJDBC 连接进行设置 - PgJDBC 试图检测并警告您 - 问题不会出现在 PostgreSQL/PgJDBC 端,而是误读文件。

具体来说,该文件看起来是 utf-8 编码的,但您正在读取它,就好像它是 latin-1 (ISO-8859-1) 编码的一样。见证这个 Python 中的简单演示,通过将本机 Unicode 字符串转换为 utf-8 然后将其解码为 latin-1 来复制您获得的结果:

>>> print u'Usuário Padrão'.encode("utf-8").decode("latin-1");
Usuário Padrão

您的应用程序很可能会以执行不适当的文本编码转换的方式将文件读入String,从文件编码到 Java 内部使用的 unicode 文本。没有可靠的方法来“自动检测”文件的编码,因此您必须在读取文件时指定输入的文本编码。Java 通常默认使用系统编码,但可以覆盖它。如果您知道文件的编码,则应在打开文件进行读取时显式传递它

您没有显示读取文件的代码,因此很难更具体,但这实际上是 Java 方面的问题,而不是 PostgreSQL 方面的问题。如果你System.out.println的 SQL 文件来自 Java,你会看到它在你发送到数据库服务器之前已经在你的 Java 字符串中被破坏了。

于 2013-07-24T02:30:14.573 回答
0

正如 jtahlborn 所说,读取文件的正确方法是这样的:

br=new BufferedReader(new InputStreamReader(new FileInputStream(arquivo),"UTF-8"));

那是我的问题,这样做,它就像一个魅力。

于 2013-07-24T18:35:19.640 回答