关于Java中FileOutputStream的一点细节问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013758734/article/details/42293391

今日没有太多工作,闲暇之余随便看了一下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别人的代码了,因为这习惯很不好,很容易出错。

猜你喜欢

转载自blog.csdn.net/u013758734/article/details/42293391