Нет, InputStream
и InputStreamReader
не одинаковы даже для 8-битных символов.
Посмотрите на метод InputStream
read()
без параметра. Возвращает int
, но согласно документации возвращается байт (от 0 до 255) или -1 для EOF. Другие методы чтения работают с массивами байтов.
InputStreamReader
наследуется от Reader
. Метод * read () 1015 * без параметра также возвращает int
. Но здесь значение int (в диапазоне от 0 до 65535) интерпретируется как символ или -1 для EOF. Другие методы чтения работают с массивами char
напрямую.
Разница заключается в кодировке. Для конструкторов InputStreamReader
требуется явная кодировка или используется кодировка платформы по умолчанию. Кодировка - это перевод между байтами и символами.
Вы сказали: "Когда я использовал InputStream, чтобы прочитать файл и преобразовать его в символ, он напечатал букву 'a'." Итак, вы прочитали байт и преобразовали его в символ вручную. Эта часть преобразования встроена в InputStreamReader
с использованием кодировки для перевода.
Даже для однобайтовых наборов символов существуют различия. Итак, вашим примером является буква «а», которая имеет шестнадцатеричное значение 61 для кодировки Windows ANSI (названной «Cp1252» в Java). Но для кодировки IBM-Thai байт 0x61 интерпретируется как "/".
Так что люди сказали правильно. InputStream
для двоичных данных и, кроме того, InputStreamReader
для текста, переводя двоичные данные в текст в соответствии с кодировкой.
Вот простой пример:
import java.io.*;
public class EncodingExample {
public static void main(String[] args) throws Exception {
// Prepare the byte buffer for character 'a' in Windows-ANSI
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PrintWriter writer = new PrintWriter(new OutputStreamWriter(baos, "Cp1252"));
writer.print('a');
writer.flush();
final byte[] buffer = baos.toByteArray();
readAsBytes(new ByteArrayInputStream(buffer));
readWithEncoding(new ByteArrayInputStream(buffer), "Cp1252");
readWithEncoding(new ByteArrayInputStream(buffer), "IBM-Thai");
}
/**
* Reads and displays the InputStream's bytes as hexadecimal.
* @param in The inputStream
* @throws Exception
*/
private static void readAsBytes(InputStream in) throws Exception {
int c;
while((c = in.read()) != -1) {
final byte b = (byte) c;
System.out.println(String.format("Hex: %x ", b));
}
}
/**
* Reads the InputStream with an InputStreamReader and the given encoding.
* Prints the resulting text to the console.
* @param in The input stream
* @param encoding The encoding
* @throws Exception
*/
private static void readWithEncoding(InputStream in, String encoding) throws Exception {
Reader reader = new InputStreamReader(in, encoding);
int c;
final StringBuilder sb = new StringBuilder();
while((c = reader.read()) != -1) {
sb.append((char) c);
}
System.out.println(String.format("Interpreted with encoding '%s': %s", encoding, sb.toString()));
}
}
Вывод:
Hex: 61
Interpreted with encoding 'Cp1252': a
Interpreted with encoding 'IBM-Thai': /