25

I need to escape the following sequence defined as a static final

final String POSIX_SIGNATURE = "ustar".concat("\0").concat("00");

How would I escape this without using the .concat() method nor the + string operator?

final String POSIX_SIGNATURE = "ustar\000"; 

This is not valid, not the same as the first one.

final String POSIX_SIGNATURE = "ustar\0\00"; 

Nor is this one either.

Kainix
  • 1,186
  • 3
  • 21
  • 33
Gala
  • 2,592
  • 3
  • 25
  • 33
  • How about https://ideone.com/Tt28vf? –  Apr 11 '16 at 19:55
  • 11
    As a side note, `String` concatenation of literals is done during compilation, so there is really no reason you can't use something like `("ustar" + "\0" + "00")` if you think it's more clear than the solutions without concatenation. See e.g. http://ideone.com/tkZneB. – Radiodef Apr 11 '16 at 20:04
  • Great question. +1. I had no idea java had variable-length octal char literals. Every day I learn more strange things about the language. – Paul Boddington Apr 11 '16 at 20:14
  • Fantastic info Radiodef! No more .concat() for me on any unimportant string! – Gala Apr 11 '16 at 20:18
  • 5
    I agree with @Radiodef, it is least surprising to see concatenation in this case than having to count zeroes and remember how many are part of the escape code and how many are actual zeroes. And since it is resolved at compile time when all values are constants, I don't see why use octal or unicode escapes. – This company is turning evil. Apr 12 '16 at 02:11

3 Answers3

24

Use a unicode escape sequence:

"\u000000"

This is the NUL character (\u0000), followed by two 0's.

Darth Android
  • 3,437
  • 18
  • 19
  • 3
    Considering the readability of this, I’d stay with `"\0"+"00"` which is a compile-time constant anyway, so the compiled code will be identical. – Holger Apr 12 '16 at 10:25
21

Darth Android has the solution, but here is the reason your attempts didn't work the way you expected.

The reason the null character is represented by \0 isn't because it's a special escape sequence just for the null character; it's because it's an octal escape sequence of up to 3 octal digits.

Your string "ustar\000" has 1 null character on the end, \000, and your string "ustar\0\00" has 2 null characters on the end, \0 and \00.

The solution is as previously mentioned by Darth Android -- use a Unicode escape, which has exactly 4 hex digits, so that extra 0 characters are just that -- 0 characters. The \u0000 is the null character, and the 5th and 6th 0s are literal 0 characters.

rgettman
  • 176,041
  • 30
  • 275
  • 357
15

You can also use

"ustar\00000"

\ can be followed by up to 3 octal digits (between 000 and 377), so this is \000 followed by "00".

Alternatively, you could do

"ustar\0\600"

This is \0 followed by \60 (octal for '0') followed by '0'.

Paul Boddington
  • 37,127
  • 10
  • 65
  • 116