我正在尝试接收以字节数组编码的图像。
如果图像不是太大,它运行良好,但是当我必须多次读取输入流以获取所有图像字节时,行:
BufferedImage img = ImageIO.read(new ByteArrayInputStream(finalData));
返回null
。
这是我的代码:
byte[]imgSize = new byte[SIZE_OF_LENGTH_ARRAY];
bis.read(imgSize, 0, SIZE_OF_LENGTH_ARRAY);
ByteBuffer bb = ByteBuffer.wrap(imgSize);
int size = bb.getInt();
System.out.println("Client: size="+size);
byte[] tmpData = new byte[size];
System.out.println("tmpData length = "+tmpData.length);
int readen = bis.read(tmpData, 0, tmpData.length);
System.out.println("readen="+readen);
byte[]finalData = new byte[size];
if(readen == size){
finalData = tmpData;
}
else{
int totalRead = readen;
int j=1;
while(totalRead<size){
System.out.println("-----------append number "+j+"----------");
System.out.println("totalRead="+totalRead);
for(int i=0;i<tmpData.length;i++){
finalData[i]=tmpData[i];
}
tmpData = new byte[size-totalRead];
int tmpRead = bis.read(tmpData, 0, size-totalRead);
System.out.println("tmpRead="+tmpRead);
for(int i=0;i<tmpData.length;i++){
finalData[i+totalRead]=tmpData[i];
}
totalRead+=tmpRead;
j++;
}
System.out.println("totalRead final="+totalRead);
}
BufferedImage img = ImageIO.read(new ByteArrayInputStream(finalData));
输出示例是:
---Client: sending mess number 1---
Client: size=31099
tmpData length = 31099
readen=31099
---Client: sending mess number 2---
Client: size=85921
tmpData length = 85921
readen=17520
-----------append number 1----------
totalRead=17520
tmpRead=17520
-----------append number 2----------
totalRead=35040
tmpRead=17520
-----------append number 3----------
totalRead=52560
tmpRead=31408
-----------append number 4----------
totalRead=83968
tmpRead=1953
totalRead final=85921
image null
虽然我读了85921个字节,但ImageIO.Read
生成了一个空图像。
答案 0 :(得分:0)
我不知道bis是什么,但这一行可能是错误的:
bis.read(imgSize, 0, SIZE_OF_LENGTH_ARRAY);
您应该始终检查读取的返回值。读取的读数可能少于您指定的值。
编辑:
这就是您通常从流中读取所有数据的方式:
byte[] buffer = new byte[1024 * 32];
int len = 0;
while ((len = in.read(buffer)) > -1) {
out.write(buffer, 0, len);
}
编辑2:
但你为什么不这样做:
ImageIO.read(bis);
答案 1 :(得分:0)
此行可能会覆盖前一次迭代时的字节:
while(totalRead<size){
System.out.println("-----------append number "+j+"----------");
System.out.println("totalRead="+totalRead);
//I suspect this is unnecessary and one source of the error
//this loop would overwrite data from the last iteration's tmpData
for(int i=0;i<tmpData.length;i++){
finalData[i]=tmpData[i];
}
tmpData = new byte[size-totalRead];
int tmpRead = bis.read(tmpData, 0, size-totalRead);
System.out.println("tmpRead="+tmpRead);
for(int i=0;i<tmpData.length;i++){
finalData[i+totalRead]=tmpData[i]; //append tmpData
}
totalRead+=tmpRead;
j++;
}
假设你在迭代中每次读取10个字节。
在第一次运行中,您将最终数据的所有元素设置为0,然后读取10个字节并设置finalData的元素0-9。
在第二次迭代中,您现在循环遍历tmpData的内容(字节0-9)并在读取字节10-19之前覆盖字节0-9并附加它们。 (到目前为止一直很好)
在第三次迭代中,你跳过tmpData的内容(现在是第二次迭代的字节10-19)并覆盖finalData中的字节0-9。所以这是一个错误。