今日没有太多工作,闲暇之余随便看了一下Apache的Http请求,想更多的了解一下HttpClient的使用,结果出了一个让本人很费解的事情,我将请求的结果写入到本地的txt文件中,可结果重视比预期的多了很多内容,好像前面的一部分内容重复写了一遍。开始使用的是BufferedInputStream和BufferedOutputStream,以为是这两个不适合文本的读写,于是换成了FileInputStream和FileOutputStream,可结果还是一样,下面看一下有问题的代码:
HttpEntity httpEntity=response.getEntity();
InputStream inputStream=httpEntity.getContent();
BufferedInputStream bufferedInputStream=new BufferedInputStream(inputStream);
BufferedOutputStream bufferedOutputStream=new
BufferedOutputStream(new FileOutputStream("D://getUserList.txt"));
int available=bufferedInputStream.available();
byte[] buffer=new byte[1024*8];
int read=bufferedInputStream.read(buffer);
while(read!=-1)
{
bufferedOutputStream.write(buffer);
read=inputStream.read(buffer);
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
bufferedInputStream.close();
inputStream.close();
上面的bufferedOutputStream.write(buffer)这句是关键,他会将buffer中所有的内容都写入到txt文件中,之所以这样写,是因为开始我没有正确理解bufferedInputStream.read(buffer),我以为bufferedInputStream在将内容读入到buffer之前,会将buffer清空,但是事实不是这样的,看一下这个源码,read(buffer)最终调用的是下面的方法:
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
看这一句:
b[off + i] = (byte)c;
原来他是从buffer的0开始写的,在写之前,buffer是有内容的,是上一次读取的内容,所以,最后在写入到txt文件时,会有上一次剩余的内容被写进去。最后发现,解决这个问题很简单,多传两个参数就OK了:
bufferedOutputStream.write(buffer,0,flag);
这个flag就是read(buffer)时返回的值,这个是本次读取内容的长度。
OK,很是舒服啊,哈哈,虽然很简单,但之前一直没有深入的理解,在网上也有很多工具类,直接拿来用,也没有仔细阅读,这是个很不好的习惯,不过我已经慢慢纠正这个了,不会再随便copy别人的代码了,因为这习惯很不好,很容易出错。