ScannerUseDelimiter
Scanner.useDelimiter is not an efficient way to read an entire InputStream

Severity
WARNING

The problem

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:

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().

Suppression

Suppress false positives by adding the suppression annotation @SuppressWarnings("ScannerUseDelimiter") to the enclosing element.