有一个UTF-8编码的文本文件,用FileReader读取到一个字符串,然后转换字符集:str=new String(str.getBytes(),"UTF-8");结果大部分中文显示正常,但最后仍有部分汉字显示为问号!

  1. public static List<String> getLines( String fileName )
  2. {
  3. List<String> lines = new ArrayList<String>();
  4. try
  5. {
  6. BufferedReader br = new BufferedReader(new FileReader(fileName));
  7. String line = null;
  8. while( ( line = br.readLine() ) != null )
  9. lines.add(new String(line.getBytes("GBK"), "UTF-8"));
  10. br.close();
  11. }
  12. catch( FileNotFoundException e )
  13. {
  14. }
  15. catch( IOException e )
  16. {
  17. }
  18. return lines;
  19. }

public static List<String> getLines( String fileName )
{
List<String> lines = new ArrayList<String>();
try
{
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = null;
while( ( line = br.readLine() ) != null )
lines.add(new String(line.getBytes("GBK"), "UTF-8"));
br.close();
}
catch( FileNotFoundException e )
{
}
catch( IOException e )
{
}
return lines;
}

文件读入时是按OS的默认字符集即GBK解码的,我先用默认字符集GBK编码str.getBytes(“GBK”),此时应该还原为文件中的字节序列了,然后再按UTF-8解码,生成的字符串按理说应该就应该是正确的。

为什么结果中还是有部分乱码呢?
问题出在FileReader读取文件的过程中,FileReader继承了InputStreamReader,但并没有实现父类中带字符集参数的构造函数,所以FileReader只能按系统默认的字符集来解码,然后在UTF-8 -> GBK -> UTF-8的过程中编码出现损失,造成结果不能还原最初的字符。

原因明确了,用InputStreamReader代替FileReader,InputStreamReader isr=new InputStreamReader(new FileInputStream(fileName),"UTF-8");这样读取文件就会直接用UTF-8解码,不用再做编码转换。

  1. public static List<String> getLines( String fileName )
  2. {
  3. List<String> lines = new ArrayList<String>();
  4. try
  5. {
  6. BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8"));
  7. String line = null;
  8. while( ( line = br.readLine() ) != null )
  9. lines.add(line);
  10. br.close();
  11. }
  12. catch( FileNotFoundException e )
  13. {
  14. }
  15. catch( IOException e )
  16. {
  17. }
  18. return lines;
  19. }

public static List<String> getLines( String fileName )
{
List<String> lines = new ArrayList<String>();
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8"));
String line = null;
while( ( line = br.readLine() ) != null )
lines.add(line);
br.close();
}
catch( FileNotFoundException e )
{
}
catch( IOException e )
{
}
return lines;
}

FileReader的编码问题的更多相关文章

  1. java指定编码的按行读写txt文件(几种读写方式的比较)

    转: java指定编码的按行读写txt文件(几种读写方式的比较) 2018年10月16日 20:40:02 Handoking 阅读数:976  版权声明:本文为博主原创文章,未经博主允许不得转载. ...

  2. J04-Java IO流总结四 《 FileReader和FileWriter 》

    FileReader和FileWriter的源码相对简单,下面通过分析它们的源码以更好地进行理解这两个流 1. FileReader FileReader实现了读取底层的字节数据并将其转换为字符数据的 ...

  3. Java IO_003.Reader与Writer--字符流以及编码对数据的操作(读取与写入)

    Java IO之Reader与Writer对象常用操作(包含了编码问题的处理) 涉及到文件(非文件夹)内容的操作,如果是纯文本的情况下,除了要用到File(见之前文章),另外就必须用到字符输入流或字符 ...

  4. Java 持久化之 --io流与序列化操作

    1)File类操作文件的属性 1.File类的常用方法 1. 文件的绝对完整路径:getAbsolutePath() 文件名:getName() 文件相对路径:getPath() 文件的上一级目录:g ...

  5. Java 持久化操作之 --io流与序列化

    1)File类操作文件的属性 1.File类的常用方法 1. 文件的绝对完整路径:getAbsolutePath() 文件名:getName() 文件相对路径:getPath() 文件的上一级目录:g ...

  6. I/O流复制文本

    package io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io. ...

  7. Java日常开发的21个坑,你踩过几个?

    前言 最近看了极客时间的<Java业务开发常见错误100例>,再结合平时踩的一些代码坑,写写总结,希望对大家有帮助,感谢阅读~ 1. 六类典型空指针问题 包装类型的空指针问题 级联调用的空 ...

  8. Java API —— 编码 & IO流( InputStreamReader & OutputStreamWriter & FileReader & FileWriter & BufferedReader & BufferedWriter )

    1.编码     1)编码表概述         由字符及其对应的数值组成的一张表     2)常见编码表         · ASCII/Unicode 字符集:ASCII是美国标准信息交换码,用一 ...

  9. FileReader读取中文txt文件编码丢失问题(乱码)(转)

    有一个UTF-8编码的文本文件,用FileReader读取到一个字符串,然后转换字符集:str=new String(str.getBytes(),"UTF-8");结果大部分中文 ...

随机推荐

  1. Python 极简教程(三)数据类型

    每种语言都有各种数据类型.这就像在现实生活中,我们计数的时候需要用到数字,在表述金额.重量.距离等需要精确计数时用到小数,在日常交谈中要用文字,等等.在计算机语言中,为了表述不同的情况,也需要用到各种 ...

  2. ubuntu,右键添加在终端中打开

    右键中添加"在终端中打开" 在终端输入  sudo apt-get install nautilus-open-terminal 重新启动, 进入操作系统就会发现单击鼠标右键就会出 ...

  3. sql for xml query sample

    sample 1: declare @x xml select @x='<ArrayOfScheduledTime> <ScheduledTime> <Recurrenc ...

  4. Android 中AIDL的使用与理解

    AIDL的使用: 最常见的aidl的使用就是Service的跨进程通信了,那么我们就写一个Activity和Service的跨进程通信吧. 首先,我们就在AS里面新建一个aidl文件(ps:现在AS建 ...

  5. jQuery笔记---选择器(三)

    1.1查找隐藏的tr元素的个数 $(“table tr:hidden”).size() 查找所有可见的tr元素的个数 $(“table tr:not(:hidden)”).size()   一般是不使 ...

  6. GTK入门学习:glade的使用

    搭建好环境后,在终端敲 glade 就可以启动glade工具. glade的总体框图: 经常使用控件选择区:列举了经常使用的控件,经常使用的有三类:顶层(主窗体等).容器(各种布局容器等).控制和显示 ...

  7. MM常用的双关语(男士必读)

    我们还是当朋友好了 (其实你还是有多馀的利用价值)我想我真的不适合你(我根本就不喜欢你.)天气好冷喔,手都快结冰了 (快牵我的手吧,大木头!)我觉得我需要更多一点的空间 (我不太想看到你啦!)其实你人 ...

  8. 如何使用google地图的api(整理)

    如何使用google地图的api(整理) 一.总结 一句话总结:直接用script标签引google地图api即可. 1.如何使用google地图的api? 页面引用javascript文件<s ...

  9. S​D​I​与​A​S​I 接口具体解释介绍

    分量编码 在对彩色电视信号进行数字化处理和传输是.一种经常使用的方式是分别对其3个分量(Y,R-Y.B-Y)进行数字化编码.这就是分量分量编码.另外还有全信号编码,全信号编码是对彩色全电视信号直接进行 ...

  10. vim修复,telnet安装启动,linux更新软件源

     vim修复: 修复前提,你到UBUNTU能够联网.否则仅仅能卸载,不能安装 1.sudo apt-get remove vim-common 2.sudo apt-get install vim ...