Java讀寫文件的編碼問題

    在處理一些日誌文件的時候,由於數據來源的服務端跟本地處理的編碼不一致,會出現許多亂七八糟的問題,比如無緣無故在文件首多了一些字符,或者寫入文件的時候少了一些內容,又或者亂碼無法顯示等。因此,在讀寫文件的時候,讀入數據流時要指明格式,從數據流寫出到文件時也要指明編碼格式,這樣來說一般沒什麼的問題,因爲你用文件原來的格式正確讀取到了,然後把流中的數據按照你需要的格式寫出了,親測有效。一般來說,讀寫文件比較常用的就是用FileReader和FileWriter,爲了使用更加方便的讀寫接口,可能會使用往這兩者外面再套一層服飾的BufferedReader和BufferedWriter或者在這兩者之上再包裝一層的IO API(Java中的io採用的就是裝飾者模式!如果你願意一層一層一層...)但是,FIleReader和FileWriter無法在你讀寫文件的時候指定文件的編碼格式,按照JDK文檔的解釋,其讀寫採用默認的編碼格式,網上資料有提到默認的編碼格式是指文件本身,也有提到指IDE平臺本身,在我測試之後發現,都沒什麼用:文件本身是utf8的,eclipse也設置成utf8的,讀入的時候在控制檯上顯示一堆亂碼,寫入文件也是一團糟;文件本身是gb2312的,在控制檯能正常顯示,寫入文件也是不得人意。

    其實,在JDK文檔對FileWrite(FileReader也類似,就以writer爲例了)的說明中還提及,除了使用默認的編碼,還可以自己去定義OutputStreamWriter的構造函數來指定編碼格式。什麼意思呢?看一下JDK文檔上的FIleWriter樹就懂了:


    也即FileWriter是在OutputStreamWriter上再包裝一層的類,因此,使用OutputStreamWriter作爲參數傳入FileWriter時,在構造OutputStreamWriter實例時可以指定文件的編碼格式。當然,使用OutputStreamWriter實例時,不一定再用FileWriter,我可以選擇使用其他IO類來包裝它,或者直接使用OutputStreamWriter示例來寫文件都可以,看個人對API的使用習慣和具體需求。Talk is cheap, show me the code.下面例子是我統計樣本文件中各個特徵取值的範圍的示例

package com.scut.mrshen;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class TestFile {

	
	public static void main(String[] args) throws IOException, InterruptedException {
		
		/**
		 * gxmobile preprogcess
		 */
		String srcPath = "E://myArch/Lab/dataYouMi/數據/gxmobile-sample-27730-GB2312.data";
		String desPath = "E://myArch/Lab/dataYouMi/數據/gxmobile-sample-featureTypes.data";
		String headerPath = "E://myArch/Lab/dataYouMi/數據/gxmobile-sample-header.txt";
	// specified charSet when using InputStreamReader or OutputStreamWriter constructor
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(srcPath)), "GB2312"));
		BufferedReader hbr = new BufferedReader(new InputStreamReader(new FileInputStream(new File(headerPath)), "GB2312"));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(desPath)), "UTF-8"));
		
	// count the feature values
		Map<Integer, Set<String>> features = new HashMap<>();
		
		String temp = null;
		while((temp = br.readLine()) != null) {
			String[] data = temp.split(",");
			for(int index = 0; index < data.length; index ++) {
				Set<String>fv = features.get(index);
				if (fv == null) {
					fv = new HashSet<String>();
				}
				fv.add(data[index]);
				features.put(index, fv);
			}
		}
		System.out.println("feature num: " + features.size());
		
		temp = hbr.readLine();
		String[]header = temp.split("\t");
	// get a sorted keySet	
		Map<Integer, Set<String>>sortedFeature = new TreeMap<>(features);
		for (int key : sortedFeature.keySet()) {
			System.out.println("index#" + key + " - valNum#" + features.get(key).size());
			bw.write("index#" + key + header[key] +  " valNum:" + sortedFeature.get(key).size() + "\n" + sortedFeature.get(key).toString() + "\n\n");
		}
		bw.flush();
		Thread.sleep(3*1000);
		
		br.close();
		hbr.close();
		bw.close();
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章