Scanner.useDelimiter("\\A") is not an efficient way to read an entire
InputStream.
Scanner scanner = new Scanner(inputStream, UTF_8).useDelimiter("\\A");
String s = scanner.hasNext() ? scanner.next() : "";
Scanner separates its input into “tokens” based on a delimiter that is a
regular expression. The regular expression \A matches the beginning of the
input, only, so there is no later delimiter and the single token consists of
every character read from the InputStream.
This works, but has multiple drawbacks:
InputStream. In that case there is no
token after \A. That’s why the extract above checks hasNext(). If you
forget to do that, you get NoSuchElementException in the empty case.It swallows IOException. Quoting the Scanner specification:
A scanner can read text from any object which implements the
Readableinterface. If an invocation of the underlying readable’sread()method throws anIOExceptionthen the scanner assumes that the end of the input has been reached. The most recentIOExceptionthrown by the underlying readable can be retrieved via theioException()method.
inputStream.readAllBytes().Instead, prefer one of the following alternatives:
Since Java 9, it has been possible to write this:
String s = new String(inputStream.readAllBytes(), UTF_8);
On Android, that does require API level 33, though. Guava’s
ByteStreams.toByteArray(inputStream)
is equivalent to inputStream.readAllBytes().
Suppress false positives by adding the suppression annotation @SuppressWarnings("ScannerUseDelimiter") to the enclosing element.