ByteArrayOutputStream.toByteArray()或从流中读取?

时间:2013-08-18 09:31:37

标签: java android stream

在我的Android应用中,我将数据存储在ByteArrayOutputStream中(目前最大约为1 MB),我想将其传递给DataOutputStream

最明显的方式当然是:

dataOS.write(byteArrayOS.toByteArray())

但是还有更复杂(但可能更有效)的方式:

ByteArrayInputStream rdr = new ByteArrayInputStream(byteArrayOS.toByteArray());
int read;
byte[] buffer = new byte[1024];
while ((read = rdr.read(buffer)) > 0){
    dataOS.write(buffer,0,read);
}

将来ByteArrayOutputStream中存储的数据量可能会增加。这两个中哪一个更有效?一次写一大块数据还是顺序写一下?

更新

DataOutputStream用于通过网络进行写入(通过UrlConnection.getOutputStream()创建)。

3 个答案:

答案 0 :(得分:3)

第一个更高效,因为它不是创建1024个字节的N个块并将它们分别发送到DataOutputStream,而是立即发送整个字节数组。

无论如何,你已经在内存中拥有了整个字节数组。可能有用的是从不从内存中字节数组(如文件或套接字输入流)读取的流中读取和写入块,因为这样可以避免将整个字节数组放在内存中。

答案 1 :(得分:1)

作为一个小组,使用streams的缓冲区为preferable。原因是,直接filesystem(瓶颈资源)访问成本高且速度慢。也就是说,streams通常是链接的,只要最后的stream(直接访问filesystem)不是reading/writing,您就可以逐个单位进行链接。< / p>

修改的 在你的情况下,没有太大的区别,但写一个更大的 chunk 的那个稍微更快。

答案 2 :(得分:0)

63行代码加速了我的应用程序:

import java.io.IOException;
import java.io.OutputStream;

public class CustomByteArrayOutputStream extends OutputStream {

    protected byte[] buf;
    protected int count;

    public CustomByteArrayOutputStream() {
        buf = new byte[32];
    }

    public CustomByteArrayOutputStream(int size) {
        if (size >= 0)
            buf = new byte[size];
        else
            throw new IllegalArgumentException("size < 0");
    }

    @Override
    public void close() throws IOException {
        super.close();
    }

    public byte[] getData() {
        return buf;
    }

    private void expand(int i) {
        if (count + i <= buf.length)
            return;
        byte[] newbuf = new byte[(count + i) * 2];
        if (buf.length > 0)
            System.arraycopy(buf, 0, newbuf, 0, count);
        buf = newbuf;
    }

    public synchronized void reset() {
        count = 0;
    }

    public int size() {
        return count;
    }

    @Override
    public synchronized void write(int oneByte) {
        if (count == buf.length)
            expand(1);
        buf[count++] = (byte) oneByte;
    }

    @Override
    public synchronized void write(byte[] buffer, int offset, int len) {
        if (len == 0)
            return;
        expand(len);
        System.arraycopy(buffer, offset, buf, count, len);
        count += len;
    }
}

如果大小未知,请执行以下操作:new CustomByteArrayOutputStream(0); 这不会创建任何内容,并且在首次写入时大小会自动增加。

getData()-在不复制数据的情况下获取数据,但不要忘记,获取数据时始终应获取数据的大小。