业务中某功能最开始是用文件读取,类似如下
RandomAccessFile raf = new RandomAccessFile(new File("daily.log"), "rw");
String line = null;
StringBuffer sb = new StringBuffer();
while((line = raf.readLine()) != null)
{
sb.append(new String(line.getBytes("ISO-8859-1"),"UTF-8"));
}
那实际上readLine是逐个字符读取的,为了提高速度,用Apache的LineIterator优化为如下方式
LineIterator iterator = FileUtils.lineIterator(new File("daily.log"));
while(iterator.hasNext())
{
line =iterator.nextLine();
sb.append(new String(line.getBytes("ISO-8859-1"),"UTF-8"));
}
系统整体速度提高了好几倍,不过测试时发现有中文时会出现乱码,为啥呢?
查看FileUtils.lineIterator方法,其实是有个encoding参数的,那如果我们没带的话会怎么样呢?IOUtils.lineIterator(in, encoding)——>InputStreamReader构造函数最后在StreamDecoder.forInputStreamReader可以看到
if(s1 == null)
s1 = Charset.defaultCharset().name();
其实是会读取默认值的,那默认值是怎么来呢?
首先,是读取jvm配置,一般来说我们会在启动参数里配置类似-Dfile.encoding=utf-8来指定编码格式;
如果启动参数没配置呢?在linux上可以通过locale方式查看,不过输入结果略过,可以直接echo $LANG查看,比如LANG=en_US.UTF-8就表示是UTF-8编码,咱国内用的windows呢,一般就是GBK编码了
知道问题了,修复就简单了,之前是读取ISO-8859-1编码转为UTF-8,保持一致即可,使用ISO-8859-1方式读取即可:
LineIterator iterator = FileUtils.lineIterator(new File("daily.log"),"ISO-8859-1");