JavaRush /Курсы /Java Collections /FileInputStream, FileOutputStream, ZipOutputStream, ZipIn...

FileInputStream, FileOutputStream, ZipOutputStream, ZipInputStream

Java Collections
1 уровень , 5 лекция
Открыта

— Привет, Амиго!

— Привет, Элли!

— Сегодня мы будем изучать потоки ввода-вывода.

— Да, я уже там все знаю. Это делается с помощью классов FileInputStream и FileOutputStream.

— Да, а какие методы есть у этих классов, знаешь?

— Конечно, вот методы FileInputStream:

Метод Описание
int read() Читает один байт и возвращает его.
int read(byte b[]) Читает массив байт, возвращает количество.
int read(byte b[], int off, int len) Читает из потока массив байт.
long skip(long n) Пропускает n байт, используется при чтении из потока.
int available() Возвращает количество байт, которое еще можно прочитать из потока.
void close() Закрывает поток.

— Все верно! А методы FileOutputStream?

— Вот:

Метод Описание
void write(int b) Записывает один байт в поток.
void write(byte b[]) Записывает массив байт в поток.
void write(byte b[], int off, int len) Записывает массив байт в поток.
void close() Закрывает поток.

— Амиго, ты меня удивляешь!

— А то!

— Отлично, тогда дам тебе два новых класса ZipInputStream и ZipOutputStream.

FileInputStream, FileOutputStream, ZipOutputStream, ZipInputStream - 1

— Zip? Это как zip-архив?

— Именно. Эти потоки предназначены для работы с файлами, которые являются zip-архивами. С помощью них можно что-то читать прямо из zip-фала или писать в него!

— Ух ты! Как интересно. Но ведь в zip-архиве может быть не один файл, как же они работают?

— А для этого есть еще один специальный класс – ZipEntry. Он представляет файл, хранящийся в архиве. Из ZipInputStream можно читать только объекты типа ZipEntry, а в ZipOutputStream можно писать только объекты ZipEntry. А вот сами ZipEntry как раз можно читать и писать как обычные файлы.

— А можно пример, как это работает?

— Конечно, вот пример, где мы создаем архив и кладем в него файл:

Код
// создаем архив
FileOutputStream zipFile = new FileOutputStream("c:/archive.zip");
ZipOutputStream zip = new ZipOutputStream(zipFile); 

//кладем в него ZipEntry – «архивный объект»
zip.putNextEntry(new ZipEntry("document.txt")); 

//копируем файл «document-for-archive.txt» в архив под именем «document.txt»
File file = new File("c:/document-for-archive.txt");
Files.copy(file.toPath(), zip);

// закрываем архив
zip.close();

— Как интересно. А разархивировать файлы так же легко?

— Ага. Вот тебе краткое описание методов классов ZipEntryZipInputStream и ZipOutputStream

ZipInputStream – это поток, поэтому все ZipEntry могут быть прочитаны только последовательно. Вот его методы:

Метод Описание
ZipEntry getNextEntry() Возвращает объект, описывающий следующий ZipEntry (пропускает все байты текущего entry).
void closeEntry() Закрывает чтение текущего ZipEntry (пропускает все байты текущего entry).
int available() Возвращает 1, если есть доступные ZipEntry, иначе 0.
int read(byte[] b, int off, int len) Читает байты из текущего ZipEntry.
long skip(long n) Пропускает n байт при чтении из потока.
void close() Закрывает поток.

— Не очень понятно.

— Лучше всего — это представить, что ты читаешь текстовый файл, а ZipEntry – это строки в нем. Можно читать как данные текущей строки – текущий ZipEntry, так и прыгать по строкам – getNextEntrycloseEntry.

— Вроде понятно, хотя не уверен, что правильно.

— ZipOutputStream и его методы:

Метод Описание
void setComment(String comment) Устанавливает комментарий к архиву.
void setMethod(int method) Указывает метод (тип) сжатия.
void setLevel(int level) Указывает степень сжатия. Чем сильнее, тем медленнее.
void putNextEntry(ZipEntry e) Добавляет новый ZipEntry.
void closeEntry() Закрывает текущий ZipEntry.
void write(byte[] b, int off, int len) Пишет набор байт в текущий ZipEntry.
void close() Закрывает поток.

— А мы же в примере выше почти ничего этого не использовали.

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

— Гм. Тоже не плохо. А ZipEntry?

— Ага. В ZipEntry дополнительно хранится только служебная информация:

Метод Описание
String getName() Внутреннее имя файла.
long getTime(), setTime(long) Время последней модификации entry.
long getCrc(), setCrc(long) Контрольная сумма.
long getSize(), setSize(long) Размер до компрессии.
int getMethod(), setMethod(int) Метод сжатия.
long get/setCompressedSize() Размер после архивации.
boolean isDirectory() Является ли entry директорией.

— Выглядит несложно и интересно, что не может не радовать!

— Отлично, тогда Диего даст тебе задачи и на эту тему.

— Язык мой – враг мой.

Комментарии (129)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
{Java_Shark} Уровень 36
14 января 2025
++
Денис Кокшаров Уровень 32
28 марта 2025
++Java_Shark
safelogj Уровень 51
22 сентября 2024

в ZipOutputStream можно писать только объекты ZipEntry.

File file = new File("c:/document-for-archive.txt");
Files.copy(file.toPath(), zip); //  ????
За что отвечает ZipEntry: Определяет метаданные для каждой записи в архиве, такие как имя файла, размер, метод сжатия, дату модификации и т.д. Не содержит само содержимое файла, только его описание. Содержимое файла передаётся в ZipOutputStream отдельно с помощью метода write(). Может использоваться как для файлов, так и для директорий (если имя записи заканчивается на "/"). Таким образом, ZipEntry отвечает за описание структуры архива (имя файла, атрибуты), а ZipOutputStream — за фактическую запись данных и их сжатие (если необходимо).
partiec Уровень 33
26 сентября 2023
недолекция
Андрей Уровень 42
9 мая 2023
была задача на архив. пропустил потому как нихера не понятно что с-под меня хотят и что это за зверь такой "архив". думал в коллекциях будут пояснения. вот они коллекции. вот он архив, но и тут через одно место инфа.
Anonymous #3059777 Уровень 51
7 апреля 2023
жаль, что нас принимают за тех, кто не в состоянии нагуглить методы и их описание.....
Popka Уровень 24
18 июля 2023
Прикол в том, что все методы можно изучить в самой идее. Просто через точку тебе всплывают все методы, ищешь нужный, тыкаешь с ctrl по нему и читаешь. Суть же лекций должна быть в разъяснениях и подробном разборе самых непонятных тем. А в итоге тут просто список методов.
Валентин Уровень 26
4 февраля 2023
Да уж... Тема вообще не раскрыта.:(
BlackGrizzli Team Уровень 46
27 января 2023
Может дальше еще расскажут, но для работы с архивом нужен класс ZipFile

ZipFile zipFile = new ZipFile("/Users/evgeniagerasimenko/Desktop/catalog/arhive.zip");  // путь к архиву
        Enumeration<? extends ZipEntry> enumeration = zipFile.entries();  // получаем линейный список всех файлов и папок архива
        while (enumeration.hasMoreElements()){ // проходимся по списку пока есть что проходить)
            ZipEntry zipEntry = enumeration.nextElement();  // получаем ZipEntry , с которого уже можем доставать информацию
            zipEntry.getName();  // получаем имя файла
            zipEntry.getComment(); // получаем комментарий к файлы
            zipEntry.getSize();  // получаем размер файла
Если нам нужно прочитать файл прямо из архива :

  ZipFile zipFile = new ZipFile("/Users/evgeniagerasimenko/Desktop/catalog/arhive.zip");
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry zipEntry = entries.nextElement();
            if(!zipEntry.isDirectory()){   // Если наш ZipEntry не папка то читаем
               BufferedReader bf =  new BufferedReader(new InputStreamReader(zipFile.getInputStream(zipEntry)));  // у нашего объекта ZipFile вернем InputStream и вставим в него текущий файл
               while (bf.ready()){
                   System.out.println(bf.readLine());
               }
            }
        }
Павел К Уровень 34
22 февраля 2023
Очень интересная штука

<? extends ZipEntry>
Правильно ли я понял - что-то, что наследуется от ZipEntry. Но без прямого указания типа.
BlackGrizzli Team Уровень 46
22 февраля 2023
Это вам расскажут далее будет опять тема дженерики. Получается как любой объект унаследованные от ZipEntry
26 января 2023
Ну.... для решения следующих задач очень мало инфы... Как то тухленько раскрыты зипы... Во время задач понимание что ZipEntry не сртрим, вообще трешак разбираться с ними самому - уже не обучение получается, а есть такое - дальше гугли сам
aDuVaN4Ik Уровень 42
14 декабря 2022
Нужны ли эти стримы при работе вообще?
Deniel Уровень 42
24 декабря 2022
хороший вопрос, тоже задаю часто его:)
aDuVaN4Ik Уровень 42
25 декабря 2022
Насчет Inputstream и OutputStream все понятно. Но эти потоки явно вызывают вопросы.
TemaCode Уровень 51
28 сентября 2022
боже, что за кoстыли 🙉😆