簡體   English   中英

如何用java將漢字保存到文件中?

[英]How to save Chinese Characters to file with java?

我用下面的代碼將漢字保存到.txt文件中,但是用寫字板打開時,卻無法讀取。

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();

我能做什么 ? 我知道如果我將漢字剪切並粘貼到寫字板中,我可以將其保存到 .txt 文件中。 我如何在 Java 中做到這一點?

這里有幾個因素在起作用:

  • 文本文件沒有用於描述其編碼的內在元數據(對於所有關於角括號稅的討論,XML都很受歡迎)
  • Windows的默認編碼仍然是8位(或雙字節)“ ANSI ”字符集,其值范圍有限 - 以此格式編寫的文本文件不可移植
  • 為了告訴ANSI文件中的Unicode文件,Windows應用程序依賴於文件開頭的字節順序標記嚴格來說不是這樣--Raymond Chen解釋 )。 從理論上講,BOM可以告訴您數據的字節順序 (字節順序)。 對於UTF-8,即使只有一個字節順序,Windows應用依賴於標記字節來自動確定它是Unicode(盡管您會注意到Notepad在其打開/保存對話框中有一個編碼選項)。
  • 說Java被破壞是錯誤的,因為它沒有自動寫入UTF-8 BOM。 例如,在Unix系統上,將BOM寫入腳本文件是錯誤的,並且許多Unix系統使用UTF-8作為其默認編碼。 有時候你不想在Windows上使用它,比如當你將數據附加到現有文件時: 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使用默認編碼,因此它是否打印任何合理的取決於您的平台和配置 。)

如果您可以依賴默認字符編碼為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();

PS如果正確配置了javac的-encoding參數,您可以在Java源代碼中使用任何Unicode字符,即使是方法和變量名也是如此。 這使得源代碼比轉義的\\uXXXX表單更具可讀性。

對提出的方法要非常小心。 甚至指定文件的編碼如下:

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

這是許多人中的一種方式。 基本上,我們只是在將字節輸出到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編碼標准,包括小寫變量名稱。 它提高了可讀性。

試試這個,

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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM