作为 Iterator[Byte] 或 Array[Byte] 从 InputStream 读取

Reading from InputStream as an Iterator[Byte] or Array[Byte]

我将数据对象表示为 Iterator[Byte],它是从 InputStream 实例创建的。

问题在于Byte是-128到127的有符号整数,而InputStream中的read方法returns是0到127的无符号整数255. 这尤其有问题,因为从语义上讲 -1 应该表示输入流的结尾。

缓解这两种类型之间不兼容的最佳方法是什么?有没有一种优雅的方法可以在一个到另一个之间进行转换?或者我应该只使用 Int 而不是 Bytes,即使它感觉不那么优雅?

def toByteIterator(in: InputStream): Iterator[Byte] = {
  Iterator.continually(in.read).takeWhile(-1 !=).map { elem =>
    convert // need to convert unsigned int to Byte here
  }
}

def toInputStream(_it: Iterator[Byte]): InputStream = {
  new InputStream {
    val (it, _) = _it.duplicate
    override def read(): Int = {
      if (it.hasNext) it.next() // need to convert Byte to unsigned int
      else -1
    }
  }
}

不幸的是,这与 class InputStream 的糟糕设计有关。如果您改用 read() you will have that problem. You should use read(byte[]) 。 但是正如您所说,您也可以使用 Int。这取决于你。

是的,您可以轻松地将 byte 转换为 int,反之亦然。

首先,int 到 byte 只需 toByte:

scala> 128.toByte
res0: Byte = -128

scala> 129.toByte
res1: Byte = -127

scala> 255.toByte
res2: Byte = -1

所以你的 elem => convert 可能只是 _.toByte.

其次,有符号的字节可以转换为无符号的 int,在 java.lang.Byte 中有一个方便的函数,叫做 toUnsignedInt:

scala> java.lang.Byte.toUnsignedInt(-1)
res1: Int = 255

scala> java.lang.Byte.toUnsignedInt(-127)
res2: Int = 129

scala> java.lang.Byte.toUnsignedInt(-128)
res3: Int = 128

所以你可以在你的第二段代码中写java.lang.Byte.toUnsignedInt(it.next())

然而,最后一个方法仅在 Java 8 之后可用。我不知道它在旧版本 Java 中的替代方法,但它的实际实现非常简单:

public static int toUnsignedInt(byte x) {
    return ((int) x) & 0xff;
}

所以你只需要写

it.next().toInt & 0xff