52

My Scala code received a binary from byte stream,it looks like [61 62 63 64].The content is "abcd". I use toString to convert it p, but failed. How do I print it as string ?

cms
  • 5,864
  • 2
  • 28
  • 31
Robin
  • 695
  • 1
  • 7
  • 10
  • 1
    Try to parse each number as a char and concate them to have a string – Quentin Jul 21 '17 at 08:58
  • [Converting byte array to string](https://stackoverflow.com/questions/43725596/converting-byte-array-to-string-and-back-again) – Sameera.San Jul 21 '17 at 09:06
  • 2
    Possible duplicate of [Byte array to String and back.. issues with -127](https://stackoverflow.com/questions/5250324/byte-array-to-string-and-back-issues-with-127) – Alexander Azarov Jul 21 '17 at 09:35

3 Answers3

104

You can always convert the byte array to a string if you know its charset,

val str = new String(bytes, StandardCharsets.UTF_8)

And the default Charset would used if you don't specify any.

Sleiman Jneidi
  • 22,907
  • 14
  • 56
  • 77
  • 3
    Curious which method is better, `(bytes.map(_.toChar)).mkString` or `new String(bytes)`? – BAE May 17 '18 at 19:50
  • 2
    @BAE this is perhaps a bit late for you; but the two could potentially produce different results. UTF-8 is a variable width encoding, so a single character could be encoded with a single byte or multiple. UTF-8 encodes ASCII characters in the same way (eg. `A` is represented by `65` in both) but most (maybe all?) other characters with multiple bytes. In short; they're the same if your string contains only ASCII characters but otherwise will produce different results. – Micheal Hill Jun 15 '18 at 01:05
  • @MichealHill assuming that the stream is a UTF-8 stream is a fairly reasonable for text payloads nowadays. The original question asked to print out a 'binary' byte stream, this particular case does not imply a string encoding. This is why it's best to provide an encoding when you're transmitting strings. (You can use frequency analysis to infer a probable string encoding if you have a text stream with no indicated encoding) – cms Jun 28 '18 at 07:49
32

You could convert the byte array to a char array, and then construct a string from that

scala> val bytes = Array[Byte]('a','b','c','d')
bytes: Array[Byte] = Array(97, 98, 99, 100)

scala> (bytes.map(_.toChar)).mkString 
res10: String = abcd

scala> 
cms
  • 5,864
  • 2
  • 28
  • 31
  • 6
    As @michael-hill already mentioned in a comment below, this can cause problems because it assumes you're working in ASCII and not UTF-8 or some other character encoding. If you were to try to convert the following (proper) UTF-8 byte array to a String... `val msg = Array[Byte](-17, -69, -65, 72, 101, 108, 108, 111)` `(msg.map(_.toChar)).mkString` You would get something that looked very weird and not the expected "Hello" that you would get from this: `new String(msg)` – Murray Todd Williams Jun 29 '18 at 20:14
  • 2
    As @cms said, this is really bad advice. Please don't do this. This can lead to silent data corruption and other hard to track down bugs – Jacob Wang Dec 04 '20 at 22:13
  • `println("".getBytes(StandardCharsets.UTF_8).length)` > 4 – tgrrr May 19 '22 at 04:59
-2

The bytes to string function I was looking for was where each byte was just a numeric value represented as a string, without any implied encoding. Thanks to the suggestions supplied here, I ended up with the following function which works for my purposes. I post it here incase it useful to someone else.

  def showBytes(bytes: Array[Byte]):String = {
    bytes.map(b => "" + b.toInt).mkString(" ")
  }

This function will return a string containing numeric values separated by spaces.

Sam Brown
  • 5
  • 1
  • 2
    Two things: 1-I don't see what all the type conversions are for. Why not just `bytes.mkString(" ")`? and 2-This answer is out of place. It doesn't answer the question asked. – jwvh Nov 21 '20 at 02:01