【问题标题】:Dealing with byte arrays of different sizes in a stream处理流中不同大小的字节数组
【发布时间】:2014-08-29 15:07:49
【问题描述】:

我有一个方法“A”在每次调用时返回一个固定大小(例如 64 字节)的byte[outputSize]。我还有一个方法“B”需要输入可变大小的字节[inputSize](例如,它可以小于或大于 64 字节)。 我想使用一个流来提供从“A”到“B”的 64 字节块序列,而不会丢失任何单个字节。

我尝试将这些 64 位块提供给 ByteArrayOutputStreamout”,直到达到 out.size > inputSize。 然后从“out”的副本创建一个ByteArrayInputStreamin”,以使用从“in”读取的byte[inputSize] 提供方法“B”。

然后重置“out”并将未读字节复制到“out”。 这是实现这一目标的正确方法还是有更简单/更快/更好的方法? 这是一个伪代码示例:

ByteArrayOutputStream out = new ByteArrayOutputStream();

public byte[] A() {
    return next64bytes;
}

public void B(byte[] bytes) throws IOException {
    while (out.size() < bytes.length) {
        out.write(A()); // feeding "out" with 64 bytes
    }
    ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
    in.read(bytes); // feeding "bytes" with bytes.length bytes
    byte unread[];
    in.read(unread = new byte[in.available()]);
    out.reset();
    out.write(unread); // basically writing unread bytes of "in" in an empty "out"
}

【问题讨论】:

  • ByteArrayOutputStream 会自动增长...你不需要手动增长它。
  • 你能说得更具体点吗?我应该查看哪一行/几行代码?
  • [OFF] 英文没有“readed”。已读。 link
  • @TamásG。我刚刚在我的真实代码中修复了它。

标签: java stream byte


【解决方案1】:

使用ByteArrayOutputStream 作为缓冲区并不是超级高效,但它确实使代码更简洁,这通常更重要。以下是您可以做得更好的方法:

public void B(byte[] bytes) {
    while (out.size() < bytes.length) {
        byte[] chunk = A();
        out.write(chunk, 0, chunk.length);
    }
    byte[] buffered = out.toByteArray();
    out.reset();
    System.arraycopy(buffered, 0, bytes, 0, bytes.length);
    out.write(buffered, bytes.length, buffered.length - bytes.length);
}

【讨论】:

  • 很好,这种混合代码将避免丑陋的 ByteArrayInputStream 解决方法,同时避免一些必要的计算并添加成员变量来记住剩余字节。如果效率与速度有关,这里并不重要,因为随机 64 字节生成器非常慢。
【解决方案2】:

为什么不简单地使用 ByteArrayOutputStream.writeTo(B)?

编辑:所以在拖出你真正想做的事情之后;为此忘记流。这个问题可以用流来解决,但它并不比复制字节简单。由于流是为 I/O 设计的,因此您最终会得到额外的异常处理,但对问题没有额外的价值。

使用成员变量来记住之前调用 B() 的剩余字节,并使用普通循环填充数组,当剩余部分用完时从 A() 请求更多数据。

【讨论】:

  • B 不是 OutputStream,你能更明确一点吗?我对 Java 有点迟钝
  • 如果我能弄清楚你想做什么;你的解释在第二句之后就不再有意义了。我只看到您正在使用非常迂回的方式将数据从一个流写入另一个流。这就是 writeTo() 可以简化事情的地方。
  • 基本上 B 是一个随机的 64 字节数组生成器。方法 A 将是从 B 构建的随机“可变长度”字节数组生成器
  • 那你为什么要使用流?为什么不简单地使用 System.arraycopy 复制字节?为什么没有调用 A() 并将 byte[] 复制到结果数组的简单循环?
  • 我认为使用流会更简单。 - 我无法编辑我之前的评论,我的意思是 A 是一个随机的 64 字节数组生成器
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 2019-08-12
相关资源
最近更新 更多