从Socket输入流精确读取指定长度的数据时,使用InputStream.read(byte b[], int off, int len) 函数,其中第三个参数表示期望从输入流读取的字节长度,但实际成功读取的长度可能小于这个值,所以当读取数据不完整时,必须有==【补读】机制==。
/**
* 从输入流循环精确读取指定长度的数据
* @param destLen - 目标长度
* @return
* @throws SocketException
*/privatestaticbyte[]ExactRead(InputStream is,int destLen)throws SocketException {
ByteArrayOutputStream bout =newByteArrayOutputStream();try{byte[] buffer =newbyte[1024];//大小为1024的缓冲区//读取'size=商'的长度for(int i =0; i <(destLen /1024); i++){//首次读取int 首次尝试读取到的长度=is.read(buffer,0,1024);// if return -1 , there is no more data because the end of the stream has been reached.// 如果返回-1,则说明socket连接已断开if(首次尝试读取到的长度==-1){return null;}
bout.write(buffer,0, 首次尝试读取到的长度);int 需补读的长度=1024-首次尝试读取到的长度;//补读if(需补读的长度 !=0){while(需补读的长度!=0){int 本次补读到的长度=is.read(buffer,0,需补读的长度);
bout.write(buffer,0, 本次补读到的长度);
需补读的长度 -= 本次补读到的长度;}}}//读取'size=余数'的长度if(destLen %1024!=0){int 首次尝试读取到的长度=is.read(buffer,0,destLen %1024);// there is no more data because the end of the stream has been reached.// 如果返回-1,则说明socket连接已断开if(首次尝试读取到的长度==-1){return null;}
bout.write(buffer,0, 首次尝试读取到的长度);int 需补读的长度= destLen %1024- 首次尝试读取到的长度;if(需补读的长度!=0){while(需补读的长度!=0){int 本次补读到的长度=is.read(buffer,0,需补读的长度);
bout.write(buffer,0, 本次补读到的长度);
需补读的长度-=本次补读到的长度;}}}}catch(SocketException e){//如果连接断开,抛出异常throw e;}catch(Exception e){
e.printStackTrace();}return bout.toByteArray();}