3

在我的 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()

4

3 回答 3

2

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

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

于 2013-08-18T09:36:26.587 回答
1

作为一个经验法则,使用带有streamsis的缓冲区preferable。原因是,直接filesystem(瓶颈资源)访问成本高且速度慢。也就是说,streams通常是链式的,只要stream最后(直接访问filesystem)不是reading/writing,一个单元一个单元就可以了。

编辑 在您的情况下,没有太大区别,但是写入较大的会快一些。

于 2013-08-18T09:41:41.087 回答
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() - 在不复制的情况下获取数据,但不要忘记在获取数据时应该始终获取数据的大小。

于 2020-04-19T19:30:07.537 回答