1

エンコーディングが UTF-8 の postgres 9.2 データベースがあります。このデータベースを更新し、.sql ファイルを読み取ってデータベースで実行するためのアプリケーション (Java で記述) があります。しかし、問題が見つかりました。これらの .sql ファイルの 1 つに、次の指示があります。

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 は通常、デフォルトでシステム エンコーディングを使用しますが、これはオーバーライドできます。ファイルのエンコーディングがわかっている場合は、読み取り用にファイルを開くときに明示的に渡す必要があります。

ファイルを読み取るコードを示していないため、具体的に説明するのは困難ですが、これは実際には PostgreSQL 側ではなく Java 側の問題です。Java から SQL ファイルを作成した場合System.out.printlnは、データベース サーバーに送信する前に、Java 文字列で既に壊れていることがわかります。

于 2013-07-24T02:30:14.573 に答える