怪啊!Stream方式读取字符文件出现许多乱码?

Stream读取字符文件之乱码问题

简介

如题,开发中我们经常使用InputStream方式来读取一些文件,如字符文件,也许你会这样做:

public static BankArea getStringFromFile(Context context){
    
    
    InputStream stream = null;
    try {
    
    
    	打开字符文件data.json
        stream = context.getAssets().open("data.json");
        StringBuilder sb = new StringBuilder();
        byte[] buffer = new byte[1024];
        int len;
        遍历整个文件不停的读取
        while((len=reader.read(buffer)) != -1){
    
    
        	转化为字符串
            String a = new String(buffer, 0, len);
            sb.append(a);
        }
        return sb.toString();
    } catch (IOException e) {
    
    
        e.printStackTrace();
    }finally {
    
    
        try {
    
    
            assert stream != null;
            stream.close();
        } catch (IOException ) {
    
    
            e.printStackTrace();
        }
    }
    return null;
}

如上诉代码,很简单的一个读取文件代码,data.json就是一个字符文件,里面有许多汉字英文等字符,代码可以正常执行,一般来说不会出现问题,但是某些特殊情况就会出现乱码问题,你知道出在哪个地方,以及为什么会出现吗?
日志打印输出乱码地方


什么情况下出现乱码?

乱码出现了,你可能会觉得是读出来的byte数据转换成String类型时,加一个UTF-8格式就可以解决了!
这是错误的!因为错误的根本原因在你的byte数据上;

根本原因:
当字符文件园园大于你定义的1024个字节byte数据后,出现的乱码情况会更加频繁,原因就在于InputStream的read是一个byte数据的读取方式,每次固定读取1024的字节,而一个汉字占用2个字节以上,所以很有可能某个1024的byte数组刚好只读取了一个汉字的部分数据,然后拿去转换为String,这样肯定会出错,因为数据都不完整


如何解决?

有两种版本,其一是将你的byte数组容量设置的足够大, 这样一次性读取完文件就不会出现了!但是这样不可取,文件太大一次性载入消耗大量内存

另一种办法就是用BufferReader方式缓存方式读取,如下(摘取关键代码):

   stream = context.getAssets().open("cityData.json");
   reader = new BufferedReader(new InputStreamReader(stream));
   StringBuilder sb = new StringBuilder();
   char[] buffer = new char[1024];
   int len;
   while((len=reader.read(buffer,0,1024)) != -1){
    
    
       String a = new String(buffer, 0, len);
       sb.append(a);
   }

为啥会这样?原因就在于BufferReader以char型为最小单位一个一个读取,确保不会读到部分字符数据,最终转换出来的就不会有乱码

猜你喜欢

转载自blog.csdn.net/jackzhouyu/article/details/107253961