如何在java中解决此编码问题

时间:2011-08-21 07:19:53

标签: java encoding utf-8

我在java中遇到这个编码问题,我实际需要处理的一个字符串是在windows命令行下运行“systeminfo”命令的响应,我需要在html文档中显示结果。问题是如果我在法语操作系统上运行我的应用程序,无论我如何尝试转换编码设置,都会在html中显示乱码。

从日志中我可以看到系统编码为“Cp1252”,代码片段如下:

String systemEncoding = System.getProperty("sun.jnu.encoding");
log.info("sun.jnu.encoding="+systemEncoding);

在html builder类中,我做了类似这样的事情:

for(String line : lines){
    line = new String(line.getBytes("Cp1252"), "UTF8");
    osReport.append(line + "<br>");
}

不幸的是,我仍然可以看到周围的那些乱码“问号”,这应该是一些法国字符。 html标题看起来像这个btw

<HEAD>
<META content="text/html; charset=UTF-8" http-equiv=Content-Type>
</HEAD>

如何获取响应字符串,请参阅以下代码..

try{
    String systemEncoding = System.getProperty("sun.jnu.encoding");
    log.info("sun.jnu.encoding="+systemEncoding);
    InputStreamReader isr;
    if (StringUtil.isEmpty(systemEncoding)) {
        isr = new InputStreamReader(is);
    } else {
        isr = new InputStreamReader(is, systemEncoding);
    }
    BufferedReader br = new BufferedReader(isr);
    String line=null;
    while ((line = br.readLine()) != null) {
        res.append(line);
        res.append(LINE_SEP);
    }   
 } catch (IOException ioe) {
    log.error("IOException occurred while printing the response",ioe);
 }

任何帮助?非常感谢!

2 个答案:

答案 0 :(得分:4)

我假设您通过Process类型调用命令。我希望systeminfo.exe使用默认的ANSI编码(法语系统上的windows-1252)来编写输出。

这意味着您可以使用default encoding来读取输入(InputStreamReader(InputStream)构造函数使用的输入。)这会将输入从默认编码转码为UTF-16。此代码使用Scanner类型和默认系统编码:

Process process = new ProcessBuilder(command).redirectErrorStream(true)
    .start();
InputStream in = process.getInputStream();
try {
  Scanner scanner = new Scanner(in);
  while (scanner.hasNextLine()) {
    lines.add(scanner.nextLine());
  }
  if (process.exitValue() != 0 || scanner.ioException() != null) {
    // throw exceptions
  }
} finally {
  in.close();
}

Java字符串总是UTF-16,所以这样的代码只是一个转码错误:

new String(line.getBytes("Cp1252"), "UTF8");

确保您正确编码HTML文件。

Charset utf8 = Charset.forName("UTF-8");
OutputStream out = new FileOutputStream(file);
Closeable stream = out;
try {
  Writer writer = new OutputStreamWriter(out, utf8);
  stream = writer;
  // write to writer here
} finally {
  stream.close();
}

我不会尝试读取或直接更改sun.jnu.encodingfile.encoding等系统属性 - 这些是JVM实现细节,不支持直接使用或配置。

如果您依靠System.out来验证字符,请确保device consuming the output将其输入解码为windows-1252。有关编码的详情,请参阅here

答案 1 :(得分:0)

如果不定义使用的字符编码,则无法使用普通字符代码点在html中显示这些法语字符。换句话说,这不起作用:

<html>
<body>
accent égu et ce çedille :D
</body>
</html>

这导致:

  

accentéguetceçedille:D

因此,您必须在元标题中 define the encoding 或用等效的转义替换所有法语字符。 Full list here.


关于系统字符编码的技巧:我不认为sun.jnu.encoding所说的是与systeminfo.exe用于输出的编码相同。