FileReader读取文件,由于不确定源文件的编码格式不同,导致读出的文件乱码的问题

本文介绍了如何利用Apache Commons IO中的IOUtils类进行文件读取,特别关注了如何处理不同编码格式之间的转换,避免了在读取文件过程中因编码不一致导致的乱码问题。通过实例演示了获取文件流、转化为字节数组、判断文件编码并正确还原文件内容的方法,有效解决了文件编码转换的困扰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接上代码:

[java]  view plain copy
  1. package org.bruce.file.handle.experiment;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5.   
  6. import org.apache.commons.io.IOUtils;  
  7.   
  8. /** 
  9.  * @author user 
  10.  * apache 的 IOUtils 这个类真的很好用~ 
  11.  */  
  12. public class TestIOUtils {  
  13.       
  14.     public static String _absPath1 = "/Users/user/Novels/txt/猎头.txt";  
  15.   
  16.     /** 
  17.      * @param args 
  18.      */  
  19.     public static void main(String[] args) throws Exception {  
  20.         // TODO Auto-generated method stub  
  21.         File f = new File(_absPath1);  
  22.         FileInputStream fis = new FileInputStream(f);  
  23.           
  24.         // 无损读取,Integer.MAX_VALUE = 21 亿 4748 万 3648 = 2G (Byte)~  
  25.         byte[] bytes = IOUtils.toByteArray(fis);  
  26.           
  27.         System.out.println(bytes.length);  
  28.           
  29.         /** 以下三句代码的效果是相通的~ */  
  30.         String str1 = new String(bytes);    // 按JVM的默认字符集 UTF-8 进行解码~  
  31. //      String str1 = new String(bytes, 0, bytes.length);   // 同上~  
  32. //      String str1 = new String(bytes, "UTF-8");  
  33.         System.out.println(str1);  
  34.           
  35.         // 还原编码  
  36.         String str2 = new String(bytes, "GBK");  
  37.         System.out.println(str2);  
  38.     }  
  39.   
  40. }  
[java]  view plain copy
  1. org.apache.commons.io.IOUtils  
[java]  view plain copy
  1. 是Apache commons IO 里面的一个工具类  
此类所在的 jar 包可以在这里下载到(只用到部分功能,我动手“精简”了一下):

http://download.youkuaiyun.com/detail/yang3wei/4163965


参考资料:http://liudeh-009.iteye.com/blog/1312117

读取一个UTF-8编码格式的文件,代码中起初用FileReader读取到一个字符串,然后转换字符集,结果就出问题了:

文件读入时是按OS的默认字符集即GBK解码的,我先用默认字符集GBK编码str.getBytes(“GBK”),此时应该还原为文件中的字节序列了,

然后再按UTF-8解码,生成的字符串按理说应该就应该是正确的。

为什么结果中还是有部分乱码呢?

问题出在FileReader读取文件的过程中,FileReader继承了InputStreamReader,但并没有实现父类中带字符集参数的构造函数,

所以FileReader只能按系统默认的字符集来解码,然后在UTF-8 -> GBK -> UTF-8的过程中编码出现损失,造成结果不能还原最初的字符。

之前还碰到过一个问题,读取一个别人上传的文件,本来约束是这个文件啊必须是UTF-8的,但是用户上传的文件,却是用GBK

编码的,导致将这个文件流读出,使用时,发现乱码无法真确识别其中信息。

如何解决呢?

首先,我不管源文件是采用什么编码,取得文件流,然后用org.apache.commons.io.IOUtils.toByteArray这个工具类中的API

FileInputStreamstream = new FileInputStream(targetFile);

byte[] bytes = IOUtils.toByteArray(stream);

这样,就将文件流转化成字节数组,并且不丢失字节;然后,每个文件都有一段头信息,描述文件的字符编码,文件大小等等的信息,同一类字符编码的文件,

头几个字节是相同的,可以以此来判断文件的字符编码类型例如:UTF-8的文件,头2个字节,分别是‘-17’和‘-69’,;接着可以用String的带字符集的构造函数,

把文件还原出来

另外,clps中不单需要读取源代码,还需要修改源代码,这时候,一定要保证编码格式的一致性,我采用的方式,模仿了文件的格式,返回给页面的

是一个文件对象,包含了文件内容实体,字符编码格式等信息,这样保存的时候,就可以得到这些信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值