编码数据库中的问题

时间:2013-07-23 20:29:43

标签: java postgresql jdbc encoding

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

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

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

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

--- --- EDIT

以下是我如何获得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();
}

3 个答案:

答案 0 :(得分:3)

这很可能是有问题的一行:

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

(看起来我的水晶球仍然运作良好!)

答案 1 :(得分:1)

为了确保我需要查看读取SQL文件的代码,但是(正如jtahlborn指出的那样)我会说你正在使用除了它真正具有的编码之外的编码来读取文件。

PgJDBC在Java端使用Unicode,并通过始终与utf-8中的服务器通信来处理客户端/服务器编码差异,让服务器执行任何所需的编码转换。因此,除非你通过你的PgJDBC连接设置client_encoding - 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 typically defaults to the system encoding, but that can be overridden。如果您知道文件的编码,则应explicitly pass it when opening the file for reading

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

答案 2 :(得分:0)

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

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

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