Удобный файловый ввод/вывод в Java
Михаил Калач
Удобный файловый ввод/вывод в Java
Пытался разобраться с BufferedReader, FileInputStream и подобными, но там сложная для новичка работа с байтами. Использовал удобный Scanner с его next*Typename*, всё работает. С точки зрения времени работы программы я хорошо сделал? И существует ли подобный "удобный" класс для вывода в файл?
Ответы:
Максим
BufferedReader и FileInputStream это совсем разные вещи.
FileInputStream - это поток байтов (реализация InputStream - любого потока символов - для конкретно работы с файлами).
FileReader - это поток символов из файла. Он поток байтов преобразовывает в поток символов. И это фактически то же, что и new StreamReader(new FileInputStream(...)), который любой поток символов (в данном случае FileInputStream - поток байтов из файла - преобразует в поток символов.
BufferedReader позволяет из потока символов доставать целые строки: new BufferedReader(new FileReader(...));
Андрей Панарин
Попробую объяснить по пальцам:
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()), чтобы накопившийся в буфере текст не остался незаписанным. Если этого не сделать, то размер полученного файла окажется кратен размеру буфера, а текст файла будет незаконченным.
|