Java InputStream读取字符串尾部会自动加0的问题


几年前写的一个从MHT(MIME)格式文件中读HTML的代码,大概代码如下:

InputStream hs = ((MimePart)part).getInputStream();
byte[] bts = new byte[hs.available()];
hs.read(bts);
tHtmlBody = new String(bts, "GBK");

一直用得挺好,但最近发现在某些服务器上读出来的HTML尾部居然会多加0,有时加一个0,有时加几十个0。但在开发的机器上一调试却又十分正常,真是奇怪。

于是开始写日志跟踪分析,最后发现问题出在available()上。出问题的MHT文件中的HTML代码采用了Quoted Printable编码,对应使用的解码类是QPDecoderStream,而继续分析这个QPDecoderStream类的available(),发现其实现代码有如下内容:

public int available() throws IOException {
  // This is bogus ! We don't really know how much
  // bytes are available *after* decoding
  return in.available();
}

很显然,这个代码的作者已经告诉我们,这个available方法是直接返回了原始数据流的大小,而不是我们想像中的解码后的大小。例如原始的QP编码文件是100字节,解码后可能就只有90字节,因实际读出来的内容比available要小,从而导致获得的HTML内容后面填0。而之前我们很多情况下是不用QP编码的,所以没发现这个问题。

解决办法是不要信任available返回的大小,还是以read返回的字节数为准:

InputStream hs = ((MimePart)part).getInputStream();
int n=hs.available();
byte[] bts = new byte[n];
n=hs.read(bts,0,n);
tHtmlBody = new String(bts,0,n, "GBK");

修改代码后再运行,果然问题解决,不再加0了。

你可能感兴趣的:(java,html,String,服务器,byte)