Чем отличаются FileInputStream и FileReader они же оба читают байты из файла?
JavaSutra
35 уровень
FileInputStream и FileReader
Решен
Комментарии (13)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Валерий Java Developer
24 июня 2018, 19:26
Они отличаются тем, что FileInputStream, как и любой потомок класса InputStream, позволяет читать из потока "сырые" байты. Если получать данные из него, то полученные байты нужно ещё приводить к нужному вам виду.
Чтобы это упростить используется класс InputStreamReader(его потомком является FileReader). Он приводит прочитанные из потока "сырые" байты к символам.
Таким образом первый класс позволяет работать на более низком уровне. Второй же добавляет удобства и позволяет читать сразу символы и работать с ними.
+7
JavaSutra
24 июня 2018, 19:58
Просто тут на примере работы FileReader тоже читает байты, не понимаю где тут символы?
0
Валерий Java Developer
24 июня 2018, 20:18решение
Нет. Reader читает символы, передает их во Writer и он их записывает. Они оба работают с символами.
Их можно заменить на FileInputStream и FileOutputStream. Результат будет тот же, но между объектами будут передавать "байтовые" данные. Эта пара классов работает с байтами.
Но это не наглядный пример, особенно с числовыми данными.
Попробуйте создать файл с текстом, прочитать его с помощью FileReader и вывести на экран считанные данные.
Потом прочитать этот же файл с помощью FileInputStream и также вывести на экран.
Тут и будет видна разница.
+5
JavaSutra
24 июня 2018, 20:58
В файле три символа abc.Концовки одинаковые 97 98 99 это эти символы. А вот начало разное у FileInputStream 239 187 191 . А у FileReader 65279. Что это значит?
0
Сергеев ВикторMaster
24 июня 2018, 22:01решение
это значит что FileReader читает символы, а FileInputStream байты.
поэтому последние 3 совпадают, а первый символ состоит из 3х байт, поэтому в первом случае он выводится как 3 элемента, а во втором как 1
+3
JavaSutra
24 июня 2018, 23:05
239 187 191 специальный символ из стандарта Юникод, вставляемый в начало текстового файла или потока для обозначения того, что в файле (потоке) используется Юникод, а также для косвенного указания кодировки и порядка байтов, с помощью которых символы Юникода были закодированы.
65279 этот символ который находится в начале файла с кодировкой UTF-8, и возможно некоторых других юникодных кодировок. Используется для индикации порядка байтов. Чтоб показать 16-битные или 32-разрядных числа используются.
Открывая файл текстовый, этот символ не увидитеть, даже если он есть.
Пересохранив файл через Notepad++ в UTF-8 без BOM проблема решается.
Если взять все это во внимания то остаются те самые байты 97 98 99 что у FileInputStream и что FileReader при считывание символов abc
0
Валерий Java Developer
24 июня 2018, 23:05
В начале вашего файла стоит BOM-символ. Если открыть файл через какой-нибудь hex-редактор, то первые 3 байта будут иметь значение: EF BB BF или 239 187 191 в десятиричной системе. FileInputStream никак не анализирует данные и просто побайтово их выдает. В этом примере - 3 байта с BOM и дальше данные.
Reader же разбирается в том, что он читает: он видит, что в первых трёх байтах хранится один символ и пытается все 3 байта прочитать как один символ.
Прочитанные символы он приводит к числу в диапазон от 0 до 65535.
Если перевести 65279 в шестнадцатиричную систему, то получится FEFF. Найдём этот код в Unicode-таблице и увидим, что это как раз BOM-символ.
Интереснее ситуация обстоит с кириллицей. Если для латиницы Reader возвращает также Unicod-код символа и результат Reader и Stream совпадают, то у кириллицы данные, возвращаемые Reader и Stream будут разными. Stream вернет коды символов в той кодировке, в какой они записаны в файле. Reader же, по крайней мере в моём случае, вернул коды каких-то левых символов. Но это уже связано с кодировками и это уже другая история.
+3
Сергеев ВикторMaster
24 июня 2018, 23:56
поставьте кодировку UTF-16 а лучше UTF-32 и сравните результат.
0
Сергеев ВикторMaster
24 июня 2018, 19:21
https://docs.oracle.com/javase/7/docs/api/java/io/FileReader.html
Convenience class for reading character files.
https://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html
A FileInputStream obtains input bytes from a file in a file system.
0
JavaSutra
24 июня 2018, 19:31
а почему все читают из 7 версии ? в девятой же более свежее?
0
Сергеев ВикторMaster
24 июня 2018, 21:59
1. не все перешли на 9 и выше, многие ещё на 8 сидят.
2. Что-то в 9 и дальше изменилось капитального?
0
JavaSutra
24 июня 2018, 22:16
Конечно !! Я уже давно на ней сижу. Все изменилось кардинально благодаря этому окошку в которому мне не надо три часа искать свои любимые классы)
+2
Сергеев ВикторMaster
24 июня 2018, 23:56
у гугла это окошко есть уже много лет
+3