我使用以下代码将中文字符保存到.txt文件中,但是当我用Wordpad打开它时,我无法读取它。
StringBuffer Shanghai_StrBuf = new StringBuffer("\u4E0A\u6D77");
boolean Append = true;
FileOutputStream fos;
fos = new FileOutputStream(FileName, Append);
for (int i = 0;i < Shanghai_StrBuf.length(); i++) {
fos.write(Shanghai_StrBuf.charAt(i));
}
fos.close();
我该怎么办?我知道如果我将中文字符剪切并粘贴到Wordpad中,我可以将其保存到.txt文件中。我如何用Java做到这一点?
答案 0 :(得分:10)
这里有几个因素在起作用:
fos = new FileOutputStream(FileName,Append);
这是一种可靠地将UTF-8数据附加到文件的方法:
private static void writeUtf8ToFile(File file, boolean append, String data)
throws IOException {
boolean skipBOM = append && file.isFile() && (file.length() > 0);
Closer res = new Closer();
try {
OutputStream out = res.using(new FileOutputStream(file, append));
Writer writer = res.using(new OutputStreamWriter(out, Charset
.forName("UTF-8")));
if (!skipBOM) {
writer.write('\uFEFF');
}
writer.write(data);
} finally {
res.close();
}
}
用法:
public static void main(String[] args) throws IOException {
String chinese = "\u4E0A\u6D77";
boolean append = true;
writeUtf8ToFile(new File("chinese.txt"), append, chinese);
}
注意:如果文件已存在并且您选择追加并且现有数据不是 UTF-8编码,那么代码将创建的唯一内容就是混乱。
以下是此代码中使用的Closer
类型:
public class Closer implements Closeable {
private Closeable closeable;
public <T extends Closeable> T using(T t) {
closeable = t;
return t;
}
@Override public void close() throws IOException {
if (closeable != null) {
closeable.close();
}
}
}
此代码使Windows风格最佳地猜测如何根据字节顺序标记读取文件:
private static final Charset[] UTF_ENCODINGS = { Charset.forName("UTF-8"),
Charset.forName("UTF-16LE"), Charset.forName("UTF-16BE") };
private static Charset getEncoding(InputStream in) throws IOException {
charsetLoop: for (Charset encodings : UTF_ENCODINGS) {
byte[] bom = "\uFEFF".getBytes(encodings);
in.mark(bom.length);
for (byte b : bom) {
if ((0xFF & b) != in.read()) {
in.reset();
continue charsetLoop;
}
}
return encodings;
}
return Charset.defaultCharset();
}
private static String readText(File file) throws IOException {
Closer res = new Closer();
try {
InputStream in = res.using(new FileInputStream(file));
InputStream bin = res.using(new BufferedInputStream(in));
Reader reader = res.using(new InputStreamReader(bin, getEncoding(bin)));
StringBuilder out = new StringBuilder();
for (int ch = reader.read(); ch != -1; ch = reader.read())
out.append((char) ch);
return out.toString();
} finally {
res.close();
}
}
用法:
public static void main(String[] args) throws IOException {
System.out.println(readText(new File("chinese.txt")));
}
(System.out使用默认编码,因此它是否打印任何合理的取决于您的平台和configuration。)
答案 1 :(得分:6)
答案 2 :(得分:4)
如果你可以依赖默认字符编码是UTF-8(或其他一些Unicode编码),你可以使用以下内容:
Writer w = new FileWriter("test.txt");
w.append("上海");
w.close();
最安全的方法是始终明确指定编码:
Writer w = new OutputStreamWriter(new FileOutputStream("test.txt"), "UTF-8");
w.append("上海");
w.close();
P.S。如果正确配置了javac的-encoding参数,则可以在Java源代码中使用任何Unicode字符,即使是方法和变量名也是如此。这使得源代码比转义\uXXXX
表单更具可读性。
答案 3 :(得分:3)
对提出的方法要非常小心。甚至指定文件的编码如下:
Writer w = new OutputStreamWriter(new FileOutputStream(“test.txt”),“UTF-8”);
如果您在Windows等操作系统下运行,将无法运行。即使将file.encoding的系统属性设置为UTF-8也无法解决问题。这是因为Java无法为文件写入字节顺序标记(BOM)。即使您在写入文件时指定编码,在Wordpad等应用程序中打开相同的文件也会将文本显示为垃圾,因为它不会检测到BOM。我尝试在Windows中运行这些示例(使用CP1252的平台/容器编码)。
以下错误用于描述Java中的问题:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
暂时的解决方案是自己编写字节顺序标记,以确保文件在其他应用程序中正确打开。有关BOM的更多详细信息,请参阅此处:
http://mindprod.com/jgloss/bom.html
有关更正确的解决方案,请参阅以下链接:
http://tripoverit.blogspot.com/2007/04/javas-utf-8-and-unicode-writing-is.html
答案 4 :(得分:1)
这是许多人中的一种方式。基本上,我们只是在将字节输出到FileOutputStream之前指定转换为UTF-8:
String FileName = "output.txt";
StringBuffer Shanghai_StrBuf=new StringBuffer("\u4E0A\u6D77");
boolean Append=true;
Writer writer = new OutputStreamWriter(new FileOutputStream(FileName,Append), "UTF-8");
writer.write(Shanghai_StrBuf.toString(), 0, Shanghai_StrBuf.length());
writer.close();
我针对http://www.fileformat.info/info/unicode/char/处的图片手动验证了这一点。将来,请遵循Java编码标准,包括小写变量名称。它提高了可读性。
答案 5 :(得分:1)
试试这个,
StringBuffer Shanghai_StrBuf=new StringBuffer("\u4E0A\u6D77");
boolean Append=true;
Writer out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(FileName,Append), "UTF8"));
for (int i=0;i<Shanghai_StrBuf.length();i++) out.write(Shanghai_StrBuf.charAt(i));
out.close();