java outputstream初始化_执行java.io.ByteArrayOutputStream.write 方法内存突然加大的原因与解决办法...

针对大文件上传过程中内存消耗过高的问题,本文分析了ByteArrayOutputStream内部实现原理,并提供了一种优化方案,通过预设缓冲区大小减少内存占用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

在项目中用有个上传功能,会把文件转换成inputstream然后转换成byte[] 数组

转换代码如下:

publicstaticbyte[] convertstream(InputStream inStream)throwsIOException {

ByteArrayOutputStream swapStream = newByteArrayOutputStream();

byte[] buff =newbyte[10240];

intrc =0;

while((rc = inStream.read(buff,0,10240)) >0) {

swapStream.write(buff, 0, rc);

}

byte[] buf = swapStream.toByteArray();

swapStream.close();

returnbuf;

}根据测试,上传一个7M的文件, 但是执行swapStream.write(buff, 0, rc); 这段代码的时候,一共消耗了20M的内存,不应该啊,内存多么重要的东西。

问题原因:

查看 ByteArrayOutputStream 的API得知

此类实现了一个输出流,其中的数据被写入一个字节数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 检索数据。

得知一个关键信息,就是缓冲区,查看ByteArrayOutputStream 源代码如下:

/**

* Creates a new byte array output stream. The buffer capacity is

* initially 32 bytes, though its size increases if necessary.

*/

publicByteArrayOutputStream() {

this(32);

}我使用ByteArrayOutputStream的时候并没有在构造函数制定缓冲区的大小,所以默认是初始化32bytes,但是对于7M大的文件来说,32bytes 远远不够,所以

ByteArrayOutputStream 缓冲区会自动增长,这个自动增长的过程,根据源码来看会有copyArray动作,所以整个write过程,消耗内存成倍增长。

源码如下:

publicsynchronizedvoidwrite(byteb[],intoff,intlen) {

if((off <0) || (off > b.length) || (len <0) ||

((off + len) > b.length) || ((off + len) 

thrownewIndexOutOfBoundsException();

} elseif(len ==0) {

return;

}

intnewcount = count + len;

if(newcount > buf.length) {

buf = Arrays.copyOf(buf, Math.max(buf.length <

}

System.arraycopy(b, off, buf, count, len);

count = newcount;

}

解决办法:

我是这么解决的,不知道还有没有更好的办法。

我们可以得到上传文件File对象的length,在创建 ByteArrayOutputStream 对象的时候把length属性放在构造函数里面:

publicstaticbyte[] convertstream(InputStream inStream,longlength)throwsIOException {

length = length > Integer.MAX_VALUE ? Integer.MAX_VALUE : length;

ByteArrayOutputStream swapStream = newByteArrayOutputStream((int)length);

byte[] buff =newbyte[10240];

intrc =0;

while((rc = inStream.read(buff,0,10240)) >0) {

swapStream.write(buff, 0, rc);

}

byte[] buf = swapStream.toByteArray();

swapStream.close();

returnbuf;

}最后测试结果

swapStream.write(buff,0, rc); 一共消耗7M内存若有更好的解决方案,请告知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值