我在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);
}
任何帮助?非常感谢!
答案 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.encoding
或file.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
用于输出的编码相同。