3

此问题涉及连接到 MySQL (5.5.16) 数据库的 Tomcat 7 Web 应用程序。

当我打开一个zip文件时,文件名以windows-1252字符集编码,Java 似乎正确解释了这些字符:

ZipFile zf = new ZipFile( zipFile, Charset.forName( "windows-1252" ) );
Enumeration entries = zf.entries();
while( entries.hasMoreElements() ) {
    ZipEntry ze = ( ZipEntry ) entries.nextElement();
    if( ! ze.isDirectory() ) {
        String name = ze.getName();
        System.out.println( name ); //prints correct filenames, e.g. café.pdf
    }
}

在 ZipFile 构造函数中省略 Charset 对象会导致异常。zip 文件中的文件名正确打印到标准输出,包括变音符号。但是,当我随后尝试将文件名存储在数据库中时,e-acute 被替换为问号(如 mysql 控制台客户端所示)。我之前将 Web 应用程序中的特殊字符插入 MySQL 没有问题。

é当我在 Java 源代码中执行 INSERT 时:

statement.executeUpdate( "insert into files (filename) values ('café.pdf')" );

éMySQL 中显示良好。

此外,我的日志文件显示逗号而不是é: caf‚.pfd

有谁知道这里会发生什么?

4

3 回答 3

1

正如您在评论部分提到的,传入的数据(压缩文件的名称)可以是不同的字符集。这对您来说将是一个问题,因为您使用的是 MySQL+JDBC 链接,并且它给您带来了很多限制(例如 MySQL 中的每列一个字符集,而 JDBC 中的每个连接只有一个字符集)。

因此,我建议您将 MySQL 端的字符集(查找和 之类的变量character_set_server)切换character_set_connection为 UTF8,因为它可以让您传输和存储您可能收到的几乎任何字符。请参阅此处了解如何正确设置 MySQL 服务器。请注意,MySQL 服务器的设置可能具有挑战性,因此请随时 PM 寻求更多帮助。JDBC 将自动适应服务器的character_set_connection变量,因此您无需更改 Java 应用程序中的任何内容。

您必须在应用程序中更改的一件事是您必须将所有传入数据转换为 UTF8 以便将其发送并存储在 MySQL 服务器上。

祝你好运。

于 2012-06-29T12:19:14.530 回答
0

在存储数据的表中,确保使用正确的排序规则以便能够存储 e-acute 字符

于 2012-06-29T10:43:05.440 回答
0

问题已解决。这篇文章建议文件中zip文件名的编码可能windows-1252不是IBM437. 改变Charset从:

ZipFile zf = new ZipFile( zipFile, Charset.forName( "windows-1252" ) );

ZipFile zf = new ZipFile( zipFile, Charset.forName( "IBM437" ) );

给出了预期的结果:在 MySQL 中保存获取的文件名时,它使用 é 正确存储。

什么地方出了错?

将 zip 文件中包含的文件名打印到标准输出

System.out.println( name );

让我错误地认为 zip 文件中的文件名被很好地解释了:当我使用windows-1252编码打开 zip 文件时,文件名很好地打印到标准输出并带有变音符号:café.pdf。使用其他字符编码,出现了不同的符号而不是 é。

但是在这个答案的帮助下打印Unicodeé- 的值时,我可以看到,当打开带有编码的 zip 文件时,实际的 Unicode 值不是(拉丁小写字母 e 带锐角),而是(单个低 - 9引号)。当我打开with charset 时,出现了正确的 Unicode 值 DID。charwindows-1252\u00e9\u201aZipFileIBM437

当然,当使用 将 a 打印String到标准输出时PrintStreamPrintStream也与某种字符编码相关联。来自PrintStreamJavadoc:

PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。

我正在使用 Windows XP。当我创建一个新的PrintStream

out = new PrintStream( System.out, true, "IBM437" );

一切都说得通:使用IBM437字符编码打开 zip 文件,并使用新的 PrintStream,é 打印正确。

没有纯文本这样的东西。

于 2012-07-02T09:41:42.760 回答