【问题标题】:Reading from InputStream as an Iterator[Byte] or Array[Byte]从 InputStream 作为 Iterator[Byte] 或 Array[Byte] 读取
【发布时间】:2015-05-15 09:57:51
【问题描述】:

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

问题在于Byte 是一个从-128 到127 的有符号整数,而InputStream 中的read 方法返回一个从0 到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
    }
  }
}

【问题讨论】:

  • 字节 b=(byte)intValue-128;
  • 这似乎很不直观,尤其是。对于那些不熟悉的人来说,甚至存在这样的问题。如果可能的话,我想避免这种情况,因为由于我正在处理的数据的性质和规模,一旦数据被损坏,就很难非常恢复数据

标签: scala byte inputstream type-conversion


【解决方案1】:

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

首先,只需 toByte 即可将 int 转换为 byte:

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

【讨论】:

    【解决方案2】:

    不幸的是,这与 InputStream 类的糟糕设计有关。如果您使用read(),您将遇到这个问题。您应该改用read(byte[])。 但正如你所说,你也可以使用Int。这取决于你。

    【讨论】:

      猜你喜欢
      • 2015-03-16
      • 2012-05-20
      • 2011-01-06
      • 2014-07-21
      • 2019-04-04
      • 1970-01-01
      • 2011-06-26
      • 2023-01-21
      相关资源
      最近更新 更多