讀寫檔案編碼方式不一致導致檔案亂碼的解決方案,不一致亂碼
這幾天在弄一個android應用的資料加密功能,為了避免加密、解密演算法被破解,我將加密和解密的核心演算法用JNI封裝起來,只把介面暴露給java層。
工作流程是這樣的:
1、通過自己寫的加密解密工具將資料加密;
2、將加密的資料放在android的asserts檔案夾下;
3、在首次使用資料時將asserts檔案夾下的資料拷貝到一個隱藏檔案夾下;
4、解密隱藏檔案夾下的檔案。
在用加密工具將資料加密好了,在程式解密這個資料檔案的過程中,發現解密出來的檔案是原來檔案大小的2倍,並且全是亂碼,跟蹤發現,主要問題出現在第3步,讀寫檔案的編碼方式不一致導致了檔案亂碼,之前我是用如下的方法來讀取asserts檔案夾下的內容的:
public static String readFileFromAssets(Context context, String fileName) throws IOException {if (null == context || TextUtils.isEmpty( fileName )){return null;}AssetManager assetManager = context.getAssets();InputStream input = assetManager.open(fileName);ByteArrayOutputStream output = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int length = 0;while ((length = input.read(buffer)) != -1) {output.write(buffer, 0, length);}output.close();input.close();return output.toString();}
問題就出在我將讀取出來的內容轉換成了字串,ByteArrayOutputStream的toString方法將檔案內容轉換成utf-8的編碼了,但用C語言讀寫檔案預設都是asii編碼方式,讀寫檔案的編碼方式不一致導致了亂碼問題,問題找到了,解決方案也就出來了,如下:
public static byte[] readFileFromAssets(Context context, String fileName) throws IOException {if (null == context || TextUtils.isEmpty( fileName )){return null;}AssetManager assetManager = context.getAssets();InputStream input = assetManager.open(fileName);ByteArrayOutputStream output = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int length = 0;while ((length = input.read(buffer)) != -1) {output.write(buffer, 0, length);}output.close();input.close();return output.toByteArray( );//return output.toString();}
將讀取asserts檔案的內容以byte數組的形式返回就可以了。
java 讀取檔案亂碼
這是因為兩你寫入檔案時的編碼和讀取檔案時的編碼方式不一致導致的。
你寫檔案時,沒有指定字元編碼,但是你讀取檔案內容時,指定了是以UTF-8編碼來讀取的。
讀寫檔案編碼必須保持一致才能正確顯示。
你可以在讀取檔案時,使用預設的編碼進行讀取:
InputStreamReader read = new InputStreamReader (new FileInputStream(file));
java中文亂碼問題
因為utf-8是linux的編碼,所以你在windos上用linux當然會亂碼。同理如果你在linux環境下,用gb一樣也會亂碼,這是作業系統決定的。所以,windows上就必須用gb,換成別的當然會亂碼了。作業系統不支援啊