JavaRush/Курсы/Java Core/Потоки для ввода/вывода файлов

Потоки для ввода/вывода файлов

Открыта

— А начнем мы с потоков для ввода/вывода файлов. Но обо всем по порядку.

Для чтений и записи файлов есть два класса:  FileInputStream и FileOutputStream. Как ты уже, наверное, догадался,  FileInputStream позволяет последовательно читать из файла байты, а FileOutputStream – записывать в файл байты. Вот какие методы есть у этих классов:

Метод Что метод делает
FileInputStream(String fileName);
— это конструктор. Позволяет указать имя файла на диске, из которого созданный объект будет читать данные.
int read();
— метод читает один байт из файла и возвращает его как результат. Тип результата расширяется до int.
int available();
— метод возвращает количество непрочитанных (доступных) байт.
void close();
— метод «закрывает» поток, вызывается после окончания работы с потоком.
Объект выполняет служебные операции, связанные с закрытием файла на диске и т.д.
Из потока больше нельзя читать данные.

Давай ради интереса посчитаем сумму всех байт в файле на диске. Вот как будет выглядеть этот код:

Подсчет суммы всех байт файла на диске
public static void main(String[] args) throws Exception {
    //создаем объект FileInputStream, привязанный к файлу «c:/data.txt».
    FileInputStream inputStream = new FileInputStream("c:/data.txt");
    long sum = 0;

    while (inputStream.available() > 0) //пока остались непрочитанные байты {
    int data = inputStream.read(); //прочитать очередной байт
    sum += data; //добавить его к общей сумме
 }
     inputStream.close(); // закрываем поток

    System.out.println(sum); //выводим сумму на экран.
}

— Мы уже раньше что-то подобное разбирали. А как устроен FileOutputStream?

— Ок. Вот, смотри:

Метод Что метод делает
FileOutputStream (String fileName);

— это конструктор. Позволяет указать имя файла на диске, в который созданный объект будет писать данные.

void write(int data);

— метод записывает очередной байт, обрезая переменную data до одного байта.

void flush();

— часто данные для записи сначала собираются в большие блоки в памяти, а потом только пишутся на диск.

Команда flush требует немедленно записать всю несохраненную информацию на диск.

void close();

— метод «закрывает» поток, вызывается после окончания работы с потоком.

Объект выполняет служебные операции, связанные с закрытием файла на диске и т.д.

В поток больше нельзя писать данные, flush при этом вызывается автоматически.

— И все?

— Да, тут фактически только один метод для записи – write, который записывает только один байт за раз. Но благодаря ему можно записать в файл сколько угодно информации.

Программирование – это процесс разбиения одной большой и сложной задачи на много маленьких. Тут происходит практически тот же процесс: чтение и запись больших данных маленькими порциями – по кусочкам – по одному байту.

Вот как можно скопировать файл на диске, пользуясь этими классами:

Копируем файл на диске
public static void main(String[] args) throws Exception {
    //Создаем поток-чтения-байт-из-файла
    FileInputStream inputStream = new FileInputStream("c:/data.txt");
    // Создаем поток-записи-байт-в-файл
    FileOutputStream outputStream = new FileOutputStream("c:/result.txt");

    while (inputStream.available() > 0) //пока есть еще непрочитанные байты {
        int data = inputStream.read(); // прочитать очередной байт в переменную data
        outputStream.write(data); // и записать его во второй поток
    }

    inputStream.close(); //закрываем оба потока. Они больше не нужны.
    outputStream.close();
}

— Спасибо, Риша. Наконец-то понял, как на самом деле работает этот код.

Комментарии (330)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Alina GabidulinaРаботает в M2
30 января, 13:28
Уже начала новый курс, но так хочется этот допройти, но вот эти устаревшие классы глаза режут.
C0N5P1RACY QA Automation Engineer
6 февраля, 13:38
Я пришел на этот старый курс с нового, не понравился мне новый, 11й уровень там взял и ушел. А вам как новый курс?
Alina GabidulinaРаботает в M2
6 февраля, 13:41
да тоже как-то не заходит, задачи простые слишком
Anonymous #3585174
Уровень 33
2 сентября 2025, 10:33
like
9 июня 2025, 07:45
Цитата из одной из прошлых лекций: "...Начиная с Java 5 классы FileInputStream и FileOutputStream стали считаться устаревшими. Поэтому для создания объектов-файлов рекомендуется использовать методы утилитного класса - java.nio.Files:
InputStream input = Files.newInputStream(Path.of("fileNames"));
OutputStream output = Files.newOutputStream(Path.of("FileName"));
"
VictorThe main expert in Automa в Строительная компани
13 мая 2025, 12:23
Я померял файл этой програмулькой - получилось 3614, посмотрел в свойствах файла - 31 байт. Кто-то врёт.
Vitalii Shevchenko
Уровень 1
27 мая 2025, 06:20
Открой таблицу ASCII и пересчитай сам, все там правильно
19 марта, 10:40
Предположу, что 3614 - это не размер файла, а сумма тех значений, что вернул метод read() в цикле.
Anonymous #3473304
Уровень 51
11 февраля 2025, 13:00
оценка лекции: 5 из 5 динозавров.
{Java_Shark}
Уровень 36
20 ноября 2024, 11:18
++
12 октября 2024, 13:13
write обрезает записываемую переменную до одного байта. А каким образом? По какому принципу он обрезает, если записываемая переменная больше байта? Сначала, с конца, с середины...?
6aHguTo
Уровень 36
30 октября 2024, 15:34
проходили в синтаксисе эту тему. кажись он забирает последние 8 бит (1 байт), остальные отбрасывает. int это 8 байт или 32 бит (вспоминает побитовые операции) 32 нолика в рядок, последние 8 штук это и есть наш байт))
Jsuccess
Уровень 1
3 декабря 2024, 17:30
Берется восемь младших битов, остальные отбрасываются.
Private Joker
Уровень 36
20 мая 2024, 13:39
Почему нельзя было сначала давать эти лекции, когда изучали потоки?
3 июня 2024, 11:41
помнишь опросник когда создавал акк в джавараш. Некоторые выбирают андроид или бэкенд и у них первый квест короче. Походу ты выбрал незнаю и тебе в первом квесте дали все сразу, но создателям этого сайта было лень переделывать квесты
Никита ОнучинFull Stack Developer в ООО Almond
2 мая 2024, 10:22
Несколько вопросов: 1. Зачем метод write принимает аргумент int, если всё равно обрезает до байта? Почему не использован тип byte? 2. Зачем нужен метод .flush? write не сразу пишет байт в файл?
Private Joker
Уровень 36
20 мая 2024, 13:38
GPT дает очень хорошие ответы на эти вопросы. И спойлер, flush реально лучше
Serge Механик
29 апреля 2024, 19:57
Интересно, а можно вместо этого while (inputStream.available() > 0) //пока есть еще непрочитанные байты { int data = inputStream.read(); // прочитать очередной байт в переменную data outputStream.write(data); // и записать его во второй поток } сразу while (inputStream.available() > 0) //пока есть еще непрочитанные байты { outputStream.write(nputStream.read()); // прочитать очередной байт и записать его во второй поток }
Private Joker
Уровень 36
20 мая 2024, 13:36
ниже читабельность кода.