我将数据对象表示为Iterator[Byte]
,它是从InputStream
实例创建的。
问题在于Byte
是从-128到127的有符号整数,而read
中的InputStream
方法返回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
}
}
}
答案 0 :(得分:1)
不幸的是,它与类InputStream
的糟糕设计有关。如果您使用read(),则会出现此问题。您应该使用read(byte[])代替。
但正如你所说,你也可以使用Int
。这取决于你。
答案 1 :(得分:1)
是的,您可以轻松地将字节转换为int,反之亦然。
首先,int to 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