Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Use StringReader when the receiving API accepts a Reader. If the API still requires an InputStream, convert the string to bytes with the format’s explicit charset and wrap them in ByteArrayInputStream. These classes are not type-compatible replacements.

Why StringBufferInputStream is deprecated

StringBufferInputStream has been deprecated since Java 1.1 and remains in current Java APIs for compatibility. It extends InputStream, but its conversion is not a real character encoding: it returns only the low eight bits of each Java char. Characters such as €, CJK text and emoji can therefore be truncated or corrupted. The official API recommends StringReader when the goal is to read a string as characters.

For example, this legacy stream does not produce the UTF-8 (or any other defined encoding) of the text:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
String text = "é € 世界";
InputStream legacy = new StringBufferInputStream(text);

That distinction matters more than the deprecation warning itself: replacing the class without checking the consuming API can either break compilation or change the data model.

The direct replacement for character-oriented code

If the next method or field expects a Reader, change the type and construct a StringReader:

// Before
StringBufferInputStream input =
    new StringBufferInputStream(text);

// After
Reader reader = new StringReader(text);

StringReader reads characters directly from the string, reports end-of-input as -1, and supports normal Reader operations such as marking and resetting. It has existed since Java 1.1, so it is suitable for projects that cannot use newer APIs.

void parse(Reader source) throws IOException {
    // Parse character data here
}

parse(new StringReader(text));

When the surrounding code follows normal reader ownership conventions, use try-with-resources:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
try (StringReader reader = new StringReader(text)) {
    // consume reader
}

The reader is backed by memory rather than a file or socket, but closing it still makes subsequent read operations invalid according to the Reader contract.

Update byte-oriented reads and buffers

A migration to a character stream is not just a constructor change. InputStream.read() returns a byte value from 0 through 255 (or -1); Reader.read() returns a character value (or -1). Likewise, change byte buffers to character buffers when the algorithm is now text-based:

// Before
byte[] buffer = new byte[1024];
int count = input.read(buffer);

// After
char[] buffer = new char[1024];
int count = reader.read(buffer);

Review offsets, terminators, checksums, framing and length calculations. String.length() counts UTF-16 code units, while an encoded byte array has a byte count; neither is automatically interchangeable.

Line-oriented input

For line parsing, wrap the reader in BufferedReader:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
try (BufferedReader reader =
         new BufferedReader(new StringReader(text))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

If an API can accept the String itself, passing it directly is usually clearer than creating a stream abstraction.

When the consumer still requires InputStream

A StringReader cannot be assigned to or cast as an InputStream:

// Does not compile
InputStream input = new StringReader(text);

Encode the text explicitly, then use ByteArrayInputStream:

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

String text = "Hello, 世界";

try (InputStream input = new ByteArrayInputStream(
        text.getBytes(StandardCharsets.UTF_8))) {
    // Call an API that requires InputStream
}

Choose the charset required by the protocol, file format or receiving API. UTF-8 is common, but it is not universally correct. Avoid the no-argument getBytes() unless platform-default behavior is explicitly intended.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Converting the byte stream back to text

When an API supplies bytes and your code needs characters, use InputStreamReader with the same charset used for encoding:

Reader reader = new InputStreamReader(input, StandardCharsets.UTF_8);

Do not encode with UTF-8 and later decode with ISO-8859-1 (or another different charset) unless intentional transcoding is taking place. InputStreamReader may read ahead from its underlying stream, so do not mix direct reads from the original stream with reads through the wrapper.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choose the migration by abstraction

Situation Use
Text API accepts Reader new StringReader(text)
API requires encoded bytes new ByteArrayInputStream(text.getBytes(charset))
Starting with bytes and reading characters new InputStreamReader(input, charset)
Data is binary, not text Keep a byte[]; use ByteArrayInputStream

Do not use a reader for compressed data, images, cryptographic material, binary serialization, checksums or protocols where byte boundaries matter.

Compatibility with old truncating behavior

Some legacy applications may have accidentally relied on the low-eight-bit results from StringBufferInputStream. Do not silently preserve that behavior. First establish whether the data was intended to be text, a specific single-byte encoding, or arbitrary binary.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • For text, use StringReader or the format’s declared encoding.
  • For intentional ISO-8859-1 bytes, say so explicitly: text.getBytes(StandardCharsets.ISO_8859_1).
  • For arbitrary binary data, retain the original byte[] instead of storing it in a String.

Modern alternative

On Java releases that provide it, Reader.of(CharSequence) is a newer option and can accept any CharSequence:

Reader reader = Reader.of(text);

It is not suitable when targeting older Java releases. For broad compatibility, continue using new StringReader(text). See the StringReader API for the version-specific note.

Migration checklist and tests

  1. Find every construction and import of StringBufferInputStream.
  2. Inspect the next method or field: does it consume Reader or InputStream?
  3. For a reader API, change declarations, parameters and byte[] buffers to character equivalents.
  4. For a byte API, select and document the required charset, then use ByteArrayInputStream.
  5. Search for assumptions that byte counts equal character counts.
  6. Test ASCII, accented Latin text, currency symbols, CJK, emoji, empty strings and different line endings.
  7. Check serialization, hashing, checksums and protocol framing for byte-level compatibility.
  8. Compile with deprecation warnings enabled, for example: javac -Xlint:deprecation -Xlint:unchecked YourClass.java.

Include a Unicode sample such as "ASCII, café, €, 世界, 😀"; ASCII-only tests can conceal both the old corruption and an incorrect replacement.

Reference documentation

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.