使用ByteBuffer,我可以将字符串转换为字节数组:
val x = ByteBuffer.allocate(10).put("Hello".getBytes()).array()
> Array[Byte] = Array(104, 101, 108, 108, 111, 0, 0, 0, 0, 0)
将字节数组转换为字符串时,我可以使用new String(x)
。
但是,字符串变为hello?????
,我需要在将字节数组转换为字符串之前对其进行修剪。我怎样才能做到这一点?
我使用此代码来减少零,但我想知道是否有更简单的方法。
def byteArrayToString(x: Array[Byte]) = {
val loc = x.indexOf(0)
if (-1 == loc)
new String(x)
else if (0 == loc)
""
else
new String(x.slice(0,loc))
}
答案 0 :(得分:6)
假设0: Byte
是一个尾随值,那么
implicit class RichToString(val x: java.nio.ByteBuffer) extends AnyVal {
def byteArrayToString() = new String( x.array.takeWhile(_ != 0), "UTF-8" )
}
因此
val x = ByteBuffer.allocate(10).put("Hello".getBytes())
x.byteArrayToString
res: String = Hello
答案 1 :(得分:4)
String constructors中有几个接受byte[]
的偏移量+长度 - 这样就无需事先创建新的修剪数组。
使用其中一个重载的构造函数可能如下所示:
def byteArrayToString(x: Array[Byte]) = {
val loc = x.indexOf(0)
if (-1 == loc)
new String(x)
else if (0 == loc)
""
else
new String(x, 0, loc, "UTF-8") // or appropriate encoding
}
或者,保持indexOf:
的微小变化def byteArrayToString(arr: Array[Byte]) = {
val loc = arr.indexOf(0)
// length passed to constructor can be 0..arr.length
new String(arr, 0, if (loc >= 0) loc else arr.length, "UTF-8")
}
或者,一行(感谢find / Option):
def byteArrayToString(arr: Array[Byte]) = {
new String(arr, 0, arr.find(_ == 0) orElse arr.length, "UTF-8")
}
关于编码的想法:
通常建议使用显式编码,并且getBytes
中应使用相同的编码作为default may change。以下是standard charset names。
字节0
可能出现在数据结尾之前的编码输出中,具体取决于字符串输入(即NUL)和编码使用
答案 2 :(得分:2)
如果您只有一个String
,我会使用.getBytes()
-
val x:Array[Byte] = "Hello".getBytes("UTF-8");
输出
x: Array[Byte] = Array(72, 101, 108, 108, 111)
对于多个String
,我会使用ByteArrayOutputStream,就像这样 -
val baos = new java.io.ByteArrayOutputStream(10); // <-- I might not use 10.
// <-- Smells of premature opt.
baos.write("Hello".getBytes("UTF-8"));
baos.write(", World!".getBytes("UTF-8"));
val x:Array[Byte] = baos.toByteArray(); // <-- x:Array[Byte], to specify the type.
输出
x: Array[Byte] = Array(72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33)
答案 3 :(得分:0)
你可以这样做:
val bb = java.nio.ByteBuffer.allocate(10).put("Hello".getBytes)
val s = new String(bb.array, 0, bb.position)
虽然这并没有在ByteBuffer中表明你已经读过任何东西。正常模式将是flip
并使用limit
,但如果您只是抓住数组,那么您可以使用position
代替clear
当{&1}} #39;在阅读更多内容之前完成。