InputStream——输入流读取数据缺失或多余现象

        写Java、android的程序员应该对InputStream再熟悉不过了。不管是文件操作还是网络传输,只要牵扯到传输数据的时候都难免会用到它。输入流能够快速的读取我们文

件或者网络的数据,但有时候也会碰到问题——数据缺失或多余。这里面其实不是输入流本身的问题,字节是完完全全读取到了,是在将编码转换成字符的时候出现了问题。是

字节数组多余空间上的默认值(0)参与了转换导致混乱而产生的。

       我们来看看InputStream读取字节的三个方法:

    read();     //从输入流里面读取一个字节,如果输入流中有数据则返回字节的整型形式;遇到输入流结束则返回-1;
    read(byte[] data);    //从输入流里面读取若干字节装填到给定的数组里面;如果输入流中字节足够则填满,否则只装填前面的部分.返回实际装填长度
    read(byte[] data,int offset,int len);    //该函数是上面函数的一般形式,可以指定读入的字节长度(len),以及读入的开始下标[offset],返回实际装填长度

       下面是一个实例:

   public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/**下面的text.txt内容是:啦啦德玛西亚,编码方式为:无BOM的UTF-8编码**/
		File file = new File("E:\\text.txt");
        try {
			FileInputStream in = new FileInputStream(file);
			byte[] bytes = new byte[25];
			//未填充字符的时候输出为:25个正方形,25字节
			System.out.println(new String(bytes));
                        //读入的字节未能填满bytes
			in.read(bytes);  
			//填充字符后,以正确的方式解码,然后输出的是:啦啦德玛西亚  ,后面跟着7个正方形。总共19字节
                        //由于后面的字符默认为0,无法按照utf-8的语义解析,故在java里面显示的是正方形。
			System.out.println(new String(bytes,"utf-8"));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
         输出的结果为:

          InputStream——输入流读取数据缺失或多余现象_第1张图片

         

     我们可以看到输出的时候多余的字节也参与了从字节转换到字符的过程,但是转换并没有成功,所以显示的还是未能识别的字符。

     解决办法:

         

/**在读取字节的时候,计算有效字节的长度,然后再创建一个大小合适的字节数组,再将该数组作为参数传递给String,指定正确的编码方式之后就可以正常显示**/

int len = 0 ; //统计每次读入字节的数量
int sum = 0 ; //全部文本的字节总数
byte[] temp = new byte[100]; // 临时字节数组,存放每次读入的字节
ByteBuffer byteBuf = ByteBuffer.allocate(1024);   //临时存放总共读取的字节,大小自己估计
while((len = in.read(temp)) != -1){
    byteBuf.put(bytes);
    sum += len;
}
byte[] bytes = new byte[sum];
for(int i = 0;i

        

    修改之后的结果:

        InputStream——输入流读取数据缺失或多余现象_第2张图片


      

    注意: 如果解码方式不对就会出现乱码!

         

     //将第一次代码的解码的方式改为"gb2312"
     System.out.println(new String(bytes,"gb2312"));
         结果:       

      

            

          总的来说,一般出现在读取字节流转换成字符显示,或者存放到文件,或者传输的时候,很多时候末尾会出现多余的奇怪的数据,或者是干脆少了一些数据都是因为多余

 的无效字节参与了转换过程,导致系统不能识别。结果有时候多了数据,有时候又少了数据。这里只列举了数据多余的情况,还有数据缺失的情况比较麻烦,我自己也是在传

 输比较大的网络数据的时候遇到的(传输的数据本身是\u的unicode字符集----\u234a\u234d\u2432(不能直接显示,需要对其进行处理转换之后才能识别),读取字节流的

 时候如果不清楚有效长度就会导致数据缺失。);

你可能感兴趣的:(字符集-编码,网络传输,文件传输)