1. 程式人生 > 實用技巧 >windows檔名編碼格式測試結果及猜想

windows檔名編碼格式測試結果及猜想

自從接觸linux,我對檔案編碼印象深刻。

但是在用windows出現一些問題,關於檔名的編碼。

windows有兩套編碼方案,utf-16和ansi。

utf-16是內部編碼方案,ansi是針對不同區域使用的外部編碼,例如gbk。

所以這套方案,對於windows語言選擇是中文的你則是utf-16和gbk。

通過windows控制面板區域可以使ansi編碼在gbk和utf-8之間變換。
但變換的時候發現檔名並沒有中文亂碼現象,通過搜尋得知檔案系統為ntfs的檔名採用utf16編碼,和ansi無關,所以無論如何變換都不會中文亂碼。

但我之前遇到的情況是怎麼來的呢?
我發現我的中文亂碼情況都是來自解壓縮,但是並不是每次解壓縮都會出現中文亂碼。
我就猜測和壓縮格式有關。
果然再多多次來回切換ansi發現:zip壓縮和解壓縮ansi不一致時會中文亂碼,而7zip和rar則不會。
通過zip壓縮解壓縮前後文件名機內碼對比,發現zip壓縮和ansi有關。
壓縮採用utf-8,解壓採用gbk,原本兩個字元變成了三個字元,符合中文編碼位元組大小規律,且通過機內碼可以完美轉換。
壓縮採用gbk,解壓縮採用utf-8,檔名中文部分�符號,可以大膽猜測因為gbk機內碼合併後變成很大的數,這個數字在utf-8內未定義,所以變成�。

所以我猜測因為壓縮演算法原因,zip壓縮的時候會將檔名以ansi的編碼格式壓縮解壓縮,其他的則統一以某種格式進行壓縮解壓。

附加java字元轉與機內碼相互轉換方法

public static String str2Hex(String input,String charset) throws UnsupportedEncodingException {
    String output = "";
    byte[] bytes= input.getBytes(charset);

    for (int i=0;i<bytes.length;i++){
        output+=Integer.toHexString(Byte.toUnsignedInt(bytes[i]))+" ";//兩個十六進位制數代表一個位元組,每個位元組留出空格
    }
    return output;
}

public static String hex2Str(String input,String charset) throws UnsupportedEncodingException {// 漢字轉機內碼
    byte[] bytes = new byte[input.length() * 2 - 1];
    String[] strings = input.split(" ");// 將字串兩個一組分段,保證每一段為1byte
    for (int i = 0; i < strings.length; i++) {
        int a = Integer.valueOf(strings[i], 16);// 將16進位制字串轉換成int型別
        bytes[i] = (byte) a;// 將int型別強轉為byte型別
    }
    String output = new String(bytes, charset);
    return output;
}