Java

Удобный файловый ввод/вывод в Java

Пытался разобраться с BufferedReader, FileInputStream и подобными, но там сложная для новичка работа с байтами. Использовал удобный Scanner с его next*Typename*, всё работает. С точки зрения времени работы программы я хорошо сделал? И существует ли подобный "удобный" класс для вывода в файл?
BufferedReader и FileInputStream это совсем разные вещи.
FileInputStream - это поток байтов (реализация InputStream - любого потока символов - для конкретно работы с файлами).
FileReader - это поток символов из файла. Он поток байтов преобразовывает в поток символов. И это фактически то же, что и new StreamReader(new FileInputStream(...)), который любой поток символов (в данном случае FileInputStream - поток байтов из файла - преобразует в поток символов.
BufferedReader позволяет из потока символов доставать целые строки: new BufferedReader(new FileReader(...));
Igor Bogutskyy
Igor Bogutskyy
99 307
Лучший ответ
Попробую объяснить по пальцам:

1. Потоки байтов

• InputStream — это входной поток, который позволяет читать байты из некоторого источника.

• FileInputStream — это субкласс InputStream, то есть разновидность входного потока. FileInputStream читает байты из файла.

• Текстовые символы (буквы, цифры пробелы) в общем случае не тождественны байтам. Существуют популярные кодировки вроде UTF-8, в которых один символ шифруется где-то 1-6 байтами. Поэтому для чтения текста входной поток байтов — не самое лучшее решение.

2. Потоки символов.

• Для чтения текста в Джаве существуют читатели, или ридеры (Reader). Ридер позволяет читать символы (char).

• InputStreamReader — это ридер, способный читать символы из произвольного входного потока байтов.

• FileReader — это ридер, читающий символы из файла.

• Вместо того, чтобы создавать new InputStreamReader(new FileInputStream(fileName)), можно просто создать new FileReader(fileName). Единственный минус — для файл-ридера всегда используется кодировка по умолчанию. Но сейчас, я думаю, это не так важно.

• Следующая проблема — чтение текста по строкам. Простой ридер ее не решает и читает текст сплошным потоком.

3. Ридер с буфером

• BufferedReader — это настоящее волшебство. Он также читает из файла текст, но читает его большими кусками с запасом, запоминая запас в своем внутреннем буфере.

• BufferedReader создается как обертка для другого ридера. Например:
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);

• Наличие буфера позволяет этому ридеру читать текст по одной строке:
String line = br.readLine();

• С его помощью можно читать и обрабатывать весь текст построчно, пока очередная строка не окажется равной null:

String line;
while ((line = br.readLine()) != null) {
//Работаем с переменной line
}

• Закрытие BufferedReader приводит к закрытию обернутого им ридера.

4. Вывод в файл

• Кроме чтения, Джава позволяет делать запись.

• Для записи байтов существуют выходные потоки: OutputStream. Например, файловый — FileOutputStream.

• Для записи текста существуют писатели, или райтеры (Writer). Например, OutputStreamWriter или FileWriter.

• Любой райтер, как и ридер, можно обернуть в реализацию с буфером — BufferedWriter. Например:

FileWriter fw = new FileWriter(outputFileName);
BufferedWriter bw = new BufferedWriter(fw);

• Для перехода на новую строку у райтера есть метод newLine().

• Основная польза райтера с буфером состоит в том, что он не пишет текст в файл при каждом обращении, а копит его в своем внутреннем буфере (около 8 КБ) и только потом выводит.

• Райтер с буфером после использования необходимо закрывать (close()) или хотя бы вычищать (flush()), чтобы накопившийся в буфере текст не остался незаписанным. Если этого не сделать, то размер полученного файла окажется кратен размеру буфера, а текст файла будет незаконченным.
Алексей Бодрый
Алексей Бодрый
81 364