Byte array trimming when converting a byte array to a string in Java / Scala

Using ByteBuffer, I can convert a string to an array of bytes:

val x = ByteBuffer.allocate(10).put("Hello".getBytes()).array()
> Array[Byte] = Array(104, 101, 108, 108, 111, 0, 0, 0, 0, 0)

When converting an array of bytes to a string, I can use new String(x). However, the string becomes hello?????, and I need to trim the byte array before converting it to a string. How can i do this?

I use this code to trim zeros, but I'm wondering if there is an easier way.

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))
}
+4
source share
4 answers

Assuming what 0: Byteis the final value, then

implicit class RichToString(val x: java.nio.ByteBuffer) extends AnyVal {
  def byteArrayToString() = new String( x.array.takeWhile(_ != 0), "UTF-8" )
}

Therefore, for

val x = ByteBuffer.allocate(10).put("Hello".getBytes())

x.byteArrayToString
res: String = Hello
+6
source

+ 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, . .

  • 0 , ( NUL) .

+4

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)
+2
source

You can do it like this:

val bb = java.nio.ByteBuffer.allocate(10).put("Hello".getBytes)
val s = new String(bb.array, 0, bb.position)

although this does not indicate in ByteBuffer that you read something. A regular template will flipuse it limit, but if you just take an array, you can just use it positioninstead and clearwhen you are done, before you read more.

0
source

Source: https://habr.com/ru/post/1542794/


All Articles