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

FileInputStream, FileOutputStream, ZipOutputStream, ZipInputStream

Открыта

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

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

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

— Да, я уже там все знаю. Это делается с помощью классов 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();

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

— Ага. Вот тебе краткое описание методов классов ZipEntry, ZipInputStream и 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, так и прыгать по строкам – getNextEntry, closeEntry.

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

— 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, 12:15
++
28 марта 2025, 09:52
++Java_Shark
safelogj Android Developer
22 сентября 2024, 17:10
в 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, 00:08
недолекция
Андрей
Уровень 42
9 мая 2023, 17:59
была задача на архив. пропустил потому как нихера не понятно что с-под меня хотят и что это за зверь такой "архив". думал в коллекциях будут пояснения. вот они коллекции. вот он архив, но и тут через одно место инфа.
Anonymous #3059777
Уровень 51
7 апреля 2023, 12:54
жаль, что нас принимают за тех, кто не в состоянии нагуглить методы и их описание.....
Popka
Уровень 24
18 июля 2023, 03:29
Прикол в том, что все методы можно изучить в самой идее. Просто через точку тебе всплывают все методы, ищешь нужный, тыкаешь с ctrl по нему и читаешь. Суть же лекций должна быть в разъяснениях и подробном разборе самых непонятных тем. А в итоге тут просто список методов.
Валентин
Уровень 26
4 февраля 2023, 18:05
Да уж... Тема вообще не раскрыта.:(
BlackGrizzli Team
Уровень 46
27 января 2023, 14:23
Может дальше еще расскажут, но для работы с архивом нужен класс 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, 05:38
Очень интересная штука
<? extends ZipEntry>
Правильно ли я понял - что-то, что наследуется от ZipEntry. Но без прямого указания типа.
BlackGrizzli Team
Уровень 46
22 февраля 2023, 11:56
Это вам расскажут далее будет опять тема дженерики. Получается как любой объект унаследованные от ZipEntry
Алексей КуренковDatabase Developer в InnoTech
26 января 2023, 07:03
Ну.... для решения следующих задач очень мало инфы... Как то тухленько раскрыты зипы... Во время задач понимание что ZipEntry не сртрим, вообще трешак разбираться с ними самому - уже не обучение получается, а есть такое - дальше гугли сам
aDuVaN4Ik
Уровень 42
14 декабря 2022, 17:54
Нужны ли эти стримы при работе вообще?
Deniel Java Developer
24 декабря 2022, 19:29
хороший вопрос, тоже задаю часто его:)
aDuVaN4Ik
Уровень 42
25 декабря 2022, 07:21
Насчет Inputstream и OutputStream все понятно. Но эти потоки явно вызывают вопросы.
TemaCode
Уровень 51
28 сентября 2022, 11:55
боже, что за кoстыли 🙉😆