我正在尝试使用java更新我的属性文件。我没有使用java.util.Properties,因为它改变了键的顺序。 我已经创建了自己的逻辑来按顺序编写密钥。
我正在使用File IO来读/写属性。 我面临的问题是,当我将日文字符串写入文件时,我需要对要写入的字符串的值进行unicode。
输入:さん
文件中的预期值:\ u3055 \ u3093
保存的价值:さん
代码:
String strJapanese = "日本語";
try {
FileOutputStream fos = new FileOutputStream("test.utf");
BufferedWriter bufferedWriter = new BufferedWriter(
new OutputStreamWriter(fos,"UTF-8"));
bufferedWriter.write(strJapanese);
bufferedWriter.close();
} catch (Exception e) {
System.out.println(e.toString());
}
我也尝试将编码格式设置为8859_1,这是由Properties类完成的。 Properties类会自动将japaneese字符串转换为unicode字符,同时将其存储到文件中。
任何帮助将不胜感激。
答案 0 :(得分:3)
使用org.apache.commons.lang.StringEscapeUtils#escapeJava(),这将为您提供Java转义字符串。
String escaptedStrJapanese = StringEscapeUtils.escapeJava("日本語");
//then write it
bufferedWriter.write(escaptedStrJapanese);
答案 1 :(得分:1)
如果要将Unicode转义序列写入文件而不是字符本身,则需要自己进行转换。使用UTF-8编码不是正确的工具(你可以毫无伤害地使用它,但它无济于事)。您还应将close()
的呼叫移至finally
阻止:
String strJapanese = "日本語";
BufferedWriter bufferedWriter = null;
try {
FileWriter fw = new FileWriter("test.utf");
BufferedWriter bufferedWriter = new BufferedWriter(fw);
int len = strJapanese.length();
for (int i = 0; i < len; ++i) {
bufferedWriter.write(String.format("\\u%04x", strJapanese.codePointAt(i)));
}
} catch (Exception e) {
System.out.println(e.toString());
} finally {
if (bufferedWriter != null) {
try {
bufferedWriter.close();
} catch (IOException e) {
System.out.println("Could not close file: " + e.toString());
}
}
}
答案 2 :(得分:0)
首先,*.properties
文件必须使用ISO 8859-1字符编码。引自javadoc:
...输入/输出流以ISO 8859-1字符编码进行编码。无法在此编码中直接表示的字符可以使用“Java™语言规范”第3.3节中定义的Unicode转义编写;在转义序列中只允许使用一个'u'字符。
所以你必须使用new OutputStreamWriter(fos, "8859_1")
。
但BufferedWriter
和OutputStreamWriter
都没有逃脱角色。这是你必须手动完成的。
这是Properties
类的用法:以下是Oracle JDK 1.8.0_20中的Properties.saveConvert()
方法:
/*
* Converts unicodes to encoded \uxxxx and escapes
* special characters with a preceding slash
*/
private String saveConvert(String theString,
boolean escapeSpace,
boolean escapeUnicode) {
int len = theString.length();
int bufLen = len * 2;
if (bufLen < 0) {
bufLen = Integer.MAX_VALUE;
}
StringBuffer outBuffer = new StringBuffer(bufLen);
for(int x=0; x<len; x++) {
char aChar = theString.charAt(x);
// Handle common case first, selecting largest block that
// avoids the specials below
if ((aChar > 61) && (aChar < 127)) {
if (aChar == '\\') {
outBuffer.append('\\'); outBuffer.append('\\');
continue;
}
outBuffer.append(aChar);
continue;
}
switch(aChar) {
case ' ':
if (x == 0 || escapeSpace)
outBuffer.append('\\');
outBuffer.append(' ');
break;
case '\t':outBuffer.append('\\'); outBuffer.append('t');
break;
case '\n':outBuffer.append('\\'); outBuffer.append('n');
break;
case '\r':outBuffer.append('\\'); outBuffer.append('r');
break;
case '\f':outBuffer.append('\\'); outBuffer.append('f');
break;
case '=': // Fall through
case ':': // Fall through
case '#': // Fall through
case '!':
outBuffer.append('\\'); outBuffer.append(aChar);
break;
default:
if (((aChar < 0x0020) || (aChar > 0x007e)) & escapeUnicode ) {
outBuffer.append('\\');
outBuffer.append('u');
outBuffer.append(toHex((aChar >> 12) & 0xF));
outBuffer.append(toHex((aChar >> 8) & 0xF));
outBuffer.append(toHex((aChar >> 4) & 0xF));
outBuffer.append(toHex( aChar & 0xF));
} else {
outBuffer.append(aChar);
}
}
}
return outBuffer.toString();
}
所以基本上会将以下行写入文件:
String line =
saveConvert(key, false, true) + "=" + saveConvert(value, false, true);