3

Using a java.util.Scanner instance, is it possible for it to return all remaining content? My scenario is that once I have read a number of fields within a String, I just want to get whatever is left and store that somewhere else. For example my content could include:

1,2,Some Garbage with \' special characters and so on

I would construct the scanner using , as the delimiter, call getInt() twice and then want to get "Some Garbage with \' special characters and so on" back in one call.

Stefan van den Akker
  • 6,661
  • 7
  • 48
  • 63
Joseph Paterson
  • 1,443
  • 4
  • 18
  • 23

2 Answers2

5

As AlexR's answer points, it should be better to read the original stream - but in my case it is consumed and can't be readed.

There is a special character / deliminter in Scanner to read 'all': \\A. So if you want the rest of the scanner you can change it:

scanner.useDelimiter("\\A");
String content = scanner.hasNext() ? scanner.next() : null;
Community
  • 1
  • 1
lucasvc
  • 767
  • 1
  • 11
  • 35
  • 1
    `\A` is _not_ a special delimiter "to read 'all'". It is a regex line anchor that normally behaves the same as `^` (match beginning of string), _unless_ "multiline mode" has been set (`Pattern.MULTILINE` in `Pattern.compile(...)`): then `^` matches after a newline and `\A` still matches the beginning of the string. In this light, what your code does, is setting the delimiter to a zero-width beginning-of-string anchor that won't match anywhere, and so it returns the rest of the string upon invoking `scanner.next()` (normally `next()` stops before a matching delimiter). It _does_ work, however. – Stefan van den Akker Jan 15 '18 at 18:45
2

There is no "good" way to do this with Scanner. You can try String next(Pattern pattern) passing to it multiline pattern like $:

Pattern p = Pattern.compile("$", Pattern.MULTILINE);

I have not tried this but it will probably work. Just do not forget to check it when several lines are remaining in your input.

BUT I think that better way is just to read from wrapped input stream using ordinary read(byte[]) method in loop. It is because Scanner is not attended to read stream as is. It is attended to read separate fields. And it does it very well. In your case you just want to read "blob", so just read it using payload stream.

AlexR
  • 114,158
  • 16
  • 130
  • 208
  • This does not work (throws an exception); I haven't been able to construct an instance where using the line anchor `$` as the sole constituent of a pattern to `Scanner.next(...)` actually _does_ work. It won't work for the empty string, for example: `new Scanner("").next("$")`. – Stefan van den Akker Jan 15 '18 at 19:27