※ 引述《tas72732002 (蔥頭)》之銘言:
: "java在執行的時候所有的字元都是被轉成unicode, 包含編譯後的.class檔案", 請問一下java在讀取與寫入的時候他的編碼是如何轉換的?
: 讀取部分 :
: 假設這時我使用FileInputStream來讀取一個utf-8的檔案,
: FileInputStream f = new FileInputStream("d:\test.txt");
: while((length = stream.read(buffer, 0, 1024)) != -1) {
: String str = new String(buffer, 0, length);
: }
: 這時我印出length, 他所顯示中文字元是占用了3個byte(length = 3)代表是UTF-8不是unicode, JVM什麼時候會將他轉成unicode呢? 不是說字元都是unicode處理嗎?
: 寫入部分 :
: OutputStream os = new FileOutputStream("d:\\one.txt", true);
: String str = "hello world 測試\r\n";
: byte[] buffer = str.getBytes();
: os.write(buffer);
: os.close();
: 這時系統自動產生的檔案是UTF-8格式, 網路上說會以作業系統的預設編碼的格式, 寫入的內容當然也是UTF-8編碼, 這部分不太確定~
: 我想請問寫入時strm 會先經過JVM將str以 unicode編碼 再轉成 UTF-8輸出嗎?
: 如果上面有錯誤的地方再麻煩各位修正
記得之前我回答過一個類似的文章,參考 #1JCcRGlx
簡單來說,這邊所謂的 Unicode 指的是 Java 儲存在 class 檔案中使用的編碼方式
當你使用 File I/O Stream 的時候,就和上面這句話無關了。
========================================================
記得:檔案在儲存的時候都以 binary 的方式看待,也就是說
當有一個 UTF-8 編碼的文字檔案內容是「好」的時候,要想像
檔案內容是 E5 A5 BD 而不是「好」這個字,這才是絕對的內容
========================================================
首先在你第一個例子中,假設這個 test.txt UTF-8 文字檔就是這個「好」字,
就代表它的內容是 E5 A5 BD , 3 bytes 你所取出的 length = 3 沒有問題
FileInputStream f = new FileInputStream("d:\test.txt");
while((length = stream.read(buffer, 0, 1024)) != -1) {
String str = new String(buffer, 0, length);
}
那麼怎樣的情況才是這邊所提到的 Unicode 呢?
答案是 str 這個變數儲存在記憶體中的時候,採用的是 Unicode 編碼
(也就是在 String 中一個名為 value 的 char[] 是採用 unicode 編碼,
Java char 的值都會是 Unicode 編碼)
接著輸出的部分: 為了方便舉例我將 str 內容改為 「好」
OutputStream os = new FileOutputStream("d:\\one.txt", true);
String str = "好";
byte[] buffer = str.getBytes();
os.write(buffer);
os.close();
那為什麼這邊會輸出 UTF-8 的文字編碼呢? 重點在於 "getBytes()" 這個 method
呼叫 getBytes() 沒帶任何參數時, Java 會以作業系統(非 JVM)預設的文字編碼
進行編碼,因此原本在 str 中儲存的是 Unicode 編碼「好」這個字,在透過
getBytes() 得到的就是 UFT-8(你的系統預設) 的編碼,所以才會建立出這個 UTF-8
文字檔。
參考:
http://www.docjar.com/docs/api/java/lang/String.html#getBytes
http://www.docjar.com/docs/api/java/lang/StringCoding.html#en
code%28char,%20int,%20int%29
(請自己接起來)
所以這個轉換並非在寫入 stream 時,而是在你呼叫 getBytes 的時候喔