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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值