Skip to content

Instantly share code, notes, and snippets.

@Shtaba09
Created November 30, 2018 00:00
Show Gist options
  • Save Shtaba09/6dbf2e8a883d991e0ee53f1f44855703 to your computer and use it in GitHub Desktop.
Save Shtaba09/6dbf2e8a883d991e0ee53f1f44855703 to your computer and use it in GitHub Desktop.
Архиватор по версии сайта Java Rush
package com.javarush.task.task31.task3110;
import com.javarush.task.task31.task3110.exception.WrongZipFileException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Archiver {
public static void main(String[] args) throws IOException {
/*ZipFileManager zipFileManager =new ZipFileManager(Paths.get("C:\\11\\22\\HS.zip"));
try {
zipFileManager.createZip(Paths.get("C:\\11\\"));
} catch (Exception e) {
e.printStackTrace();
}*/
Operation operation = null;
do {
try {
operation = askOperation();
CommandExecutor.execute(operation);
} catch (WrongZipFileException e) {
ConsoleHelper.writeMessage("Вы не выбрали файл архива или выбрали неверный файл.");
} catch (Exception e) {
ConsoleHelper.writeMessage("Произошла ошибка. Проверьте введенные данные.");
}
} while (operation != Operation.EXIT);
}
public static Operation askOperation() throws IOException {
ConsoleHelper.writeMessage("");
ConsoleHelper.writeMessage("Выберите операцию:");
ConsoleHelper.writeMessage(String.format("\t %d - упаковать файлы в архив", Operation.CREATE.ordinal()));
ConsoleHelper.writeMessage(String.format("\t %d - добавить файл в архив", Operation.ADD.ordinal()));
ConsoleHelper.writeMessage(String.format("\t %d - удалить файл из архива", Operation.REMOVE.ordinal()));
ConsoleHelper.writeMessage(String.format("\t %d - распаковать архив", Operation.EXTRACT.ordinal()));
ConsoleHelper.writeMessage(String.format("\t %d - просмотреть содержимое архива", Operation.CONTENT.ordinal()));
ConsoleHelper.writeMessage(String.format("\t %d - выход", Operation.EXIT.ordinal()));
return Operation.values()[ConsoleHelper.readInt()];
}
}
package com.javarush.task.task31.task3110.command;
public interface Command {
void execute() throws Exception;
}
package com.javarush.task.task31.task3110.command;
import com.javarush.task.task31.task3110.ConsoleHelper;
public class ExitCommand implements Command {
@Override
public void execute() throws Exception {
ConsoleHelper.writeMessage("До встречи!");
}
}
package com.javarush.task.task31.task3110.command;
import com.javarush.task.task31.task3110.ConsoleHelper;
import com.javarush.task.task31.task3110.ZipFileManager;
import com.javarush.task.task31.task3110.exception.PathIsNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ZipAddCommand extends ZipCommand {
@Override
public void execute() throws Exception {
try {
ConsoleHelper.writeMessage("Добавление нового файла в архив.");
ZipFileManager zipFileManager = getZipFileManager();
ConsoleHelper.writeMessage("Введите полное имя файла для добавления:");
Path sourcePath = Paths.get(ConsoleHelper.readString());
zipFileManager.addFile(sourcePath);
ConsoleHelper.writeMessage("Добавление в архив завершено.");
} catch (PathIsNotFoundException e) {
ConsoleHelper.writeMessage("Файл не был найден.");
}
}
}
package com.javarush.task.task31.task3110.command;
import com.javarush.task.task31.task3110.ConsoleHelper;
import com.javarush.task.task31.task3110.ZipFileManager;
import java.nio.file.Path;
import java.nio.file.Paths;
public abstract class ZipCommand implements Command {
public ZipFileManager getZipFileManager() throws Exception{
ConsoleHelper.writeMessage("Введите полный путь файла архива:");
Path zipPath = Paths.get(ConsoleHelper.readString());
return new ZipFileManager(zipPath);
}
}
package com.javarush.task.task31.task3110.command;
import com.javarush.task.task31.task3110.ConsoleHelper;
import com.javarush.task.task31.task3110.FileProperties;
import com.javarush.task.task31.task3110.ZipFileManager;
import java.util.List;
public class ZipContentCommand extends ZipCommand {
@Override
public void execute() throws Exception {
ConsoleHelper.writeMessage("Просмотр содержимого архива.");
ZipFileManager zipFileManager = getZipFileManager();
ConsoleHelper.writeMessage("Содержимое архива:");
List<FileProperties> files = zipFileManager.getFilesList();
for (FileProperties file : files) {
ConsoleHelper.writeMessage(file.toString());
}
ConsoleHelper.writeMessage("Содержимое архива прочитано.");
}
}
package com.javarush.task.task31.task3110.command;
import com.javarush.task.task31.task3110.ConsoleHelper;
import com.javarush.task.task31.task3110.ZipFileManager;
import com.javarush.task.task31.task3110.exception.PathIsNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ZipCreateCommand extends ZipCommand {
@Override
public void execute() throws Exception {
try {
ConsoleHelper.writeMessage("Создание архива.");
ZipFileManager zipFileManager = getZipFileManager();
ConsoleHelper.writeMessage("Введите полное имя файла или директории для архивации:");
Path sourcePath = Paths.get(ConsoleHelper.readString());
zipFileManager.createZip(sourcePath);
ConsoleHelper.writeMessage("Архив создан.");
} catch (PathIsNotFoundException e) {
ConsoleHelper.writeMessage("Вы неверно указали имя файла или директории.");
}
}
}
package com.javarush.task.task31.task3110.command;
import com.javarush.task.task31.task3110.ConsoleHelper;
import com.javarush.task.task31.task3110.ZipFileManager;
import com.javarush.task.task31.task3110.exception.PathIsNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ZipExtractCommand extends ZipCommand {
@Override
public void execute() throws Exception {
try {
ConsoleHelper.writeMessage("Распаковка архива.");
ZipFileManager zipFileManager = getZipFileManager();
ConsoleHelper.writeMessage("Введите путь для распаковки:");
Path destinationPath = Paths.get(ConsoleHelper.readString());
zipFileManager.extractAll(destinationPath);
ConsoleHelper.writeMessage("Архив был распакован.");
} catch (PathIsNotFoundException e) {
ConsoleHelper.writeMessage("Неверный путь для распаковки.");
}
}
}
package com.javarush.task.task31.task3110.command;
import com.javarush.task.task31.task3110.ConsoleHelper;
import com.javarush.task.task31.task3110.ZipFileManager;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ZipRemoveCommand extends ZipCommand {
@Override
public void execute() throws Exception {
ConsoleHelper.writeMessage("Удаление файла из архива.");
ZipFileManager zipFileManager = getZipFileManager();
ConsoleHelper.writeMessage("Введите полный путь файла в архиве:");
Path sourcePath = Paths.get(ConsoleHelper.readString());
zipFileManager.removeFile(sourcePath);
ConsoleHelper.writeMessage("Удаление из архива завершено.");
}
}
package com.javarush.task.task31.task3110;
import com.javarush.task.task31.task3110.command.*;
import java.util.HashMap;
import java.util.Map;
public class CommandExecutor {
private static final Map<Operation, Command> allKnownCommandsMap = new HashMap<>();
static {
allKnownCommandsMap.put(Operation.CREATE, new ZipCreateCommand());
allKnownCommandsMap.put(Operation.ADD, new ZipAddCommand());
allKnownCommandsMap.put(Operation.REMOVE, new ZipRemoveCommand());
allKnownCommandsMap.put(Operation.EXTRACT, new ZipExtractCommand());
allKnownCommandsMap.put(Operation.CONTENT, new ZipContentCommand());
allKnownCommandsMap.put(Operation.EXIT, new ExitCommand());
}
private CommandExecutor() {
}
public static void execute(Operation operation) throws Exception {
allKnownCommandsMap.get(operation).execute();
}
}
package com.javarush.task.task31.task3110;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ConsoleHelper {
private static BufferedReader bis = new BufferedReader(new InputStreamReader(System.in));
public static void writeMessage(String message) {
System.out.println(message);
}
public static String readString() throws IOException {
String text = bis.readLine();
return text;
}
public static int readInt() throws IOException {
String text = readString();
return Integer.parseInt(text.trim());
}
}
package com.javarush.task.task31.task3110.exception;
public class PathIsNotFoundException extends Exception {
}
package com.javarush.task.task31.task3110.exception;
public class WrongZipFileException extends Exception {
}
package com.javarush.task.task31.task3110;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class FileManager {
private Path rootPath;
private List<Path> fileList;
public FileManager(Path rootPath) throws IOException {
this.rootPath = rootPath;
this.fileList = new ArrayList<>();
collectFileList(rootPath);
}
public List<Path> getFileList() {
return fileList;
}
private void collectFileList(Path path) throws IOException {
// Добавляем только файлы
if (Files.isRegularFile(path)) {
Path relativePath = rootPath.relativize(path);
fileList.add(relativePath);
}
// Добавляем содержимое директории
if (Files.isDirectory(path)) {
// Рекурсивно проходимся по всему содержмому директории
// Чтобы не писать код по вызову close для DirectoryStream, обернем вызов newDirectoryStream в try-with-resources
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path)) {
for (Path file : directoryStream) {
collectFileList(file);
}
}
}
}
}
package com.javarush.task.task31.task3110;
public class FileProperties {
private String name;
private long size;
private long compressedSize;
private int compressionMethod;
public FileProperties(String name, long size, long compressedSize, int compressionMethod) {
this.name = name;
this.size = size;
this.compressedSize = compressedSize;
this.compressionMethod = compressionMethod;
}
public String getName() {
return name;
}
public long getSize() {
return size;
}
public long getCompressedSize() {
return compressedSize;
}
public int getCompressionMethod() {
return compressionMethod;
}
public long getCompressionRatio() {
// Вычисляем степень сжатия
return 100 - ((compressedSize * 100) / size);
}
@Override
public String toString() {
// Строим красивую строку из свойств
StringBuilder builder = new StringBuilder();
builder.append(name);
if (size > 0) {
builder.append("\t");
builder.append(size / 1024);
builder.append(" Kb (");
builder.append(compressedSize / 1024);
builder.append(" Kb) сжатие: ");
builder.append(getCompressionRatio());
builder.append("%");
}
return builder.toString();
}
}
package com.javarush.task.task31.task3110;
public enum Operation {
CREATE("упаковать файлы в архив"),
ADD("добавить файл в архив"),
REMOVE("удалить файл из архива"),
EXTRACT("распаковать архив"),
CONTENT("просмотреть содержимое архива"),
EXIT("выход");
private String comment;
Operation(String comment) {
this.comment = comment;
}
@Override
public String toString() {
return comment;
}
}
package com.javarush.task.task31.task3110;
import com.javarush.task.task31.task3110.exception.PathIsNotFoundException;
import com.javarush.task.task31.task3110.exception.WrongZipFileException;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipFileManager {
// Полный путь zip файла
private final Path zipFile;
public ZipFileManager(Path zipFile) {
this.zipFile = zipFile;
}
public void createZip(Path source) throws Exception {
// Проверяем, существует ли директория, где будет создаваться архив
// При необходимости создаем ее
Path zipDirectory = zipFile.getParent();
if (Files.notExists(zipDirectory))
Files.createDirectories(zipDirectory);
// Создаем zip поток
try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFile))) {
if (Files.isDirectory(source)) {
// Если архивируем директорию, то нужно получить список файлов в ней
FileManager fileManager = new FileManager(source);
List<Path> fileNames = fileManager.getFileList();
// Добавляем каждый файл в архив
for (Path fileName : fileNames)
addNewZipEntry(zipOutputStream, source, fileName);
} else if (Files.isRegularFile(source)) {
// Если архивируем отдельный файл, то нужно получить его директорию и имя
addNewZipEntry(zipOutputStream, source.getParent(), source.getFileName());
} else {
// Если переданный source не директория и не файл, бросаем исключение
throw new PathIsNotFoundException();
}
}
}
public void extractAll(Path outputFolder) throws Exception {
// Проверяем существует ли zip файл
if (!Files.isRegularFile(zipFile)) {
throw new WrongZipFileException();
}
try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile))) {
// Создаем директорию вывода, если она не существует
if (Files.notExists(outputFolder))
Files.createDirectories(outputFolder);
// Проходимся по содержимому zip потока (файла)
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
String fileName = zipEntry.getName();
Path fileFullName = outputFolder.resolve(fileName);
// Создаем необходимые директории
Path parent = fileFullName.getParent();
if (Files.notExists(parent))
Files.createDirectories(parent);
try (OutputStream outputStream = Files.newOutputStream(fileFullName)) {
copyData(zipInputStream, outputStream);
}
zipEntry = zipInputStream.getNextEntry();
}
}
}
public void removeFile(Path path) throws Exception {
removeFiles(Collections.singletonList(path));
}
public void removeFiles(List<Path> pathList) throws Exception {
// Проверяем существует ли zip файл
if (!Files.isRegularFile(zipFile)) {
throw new WrongZipFileException();
}
// Создаем временный файл
Path tempZipFile = Files.createTempFile(null, null);
try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(tempZipFile))) {
try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile))) {
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
Path archivedFile = Paths.get(zipEntry.getName());
if (!pathList.contains(archivedFile)) {
String fileName = zipEntry.getName();
zipOutputStream.putNextEntry(new ZipEntry(fileName));
copyData(zipInputStream, zipOutputStream);
zipOutputStream.closeEntry();
zipInputStream.closeEntry();
}
else {
ConsoleHelper.writeMessage(String.format("Файл '%s' удален из архива.", archivedFile.toString()));
}
zipEntry = zipInputStream.getNextEntry();
}
}
}
// Перемещаем временный файл на место оригинального
Files.move(tempZipFile, zipFile, StandardCopyOption.REPLACE_EXISTING);
}
public void addFile(Path absolutePath) throws Exception {
addFiles(Collections.singletonList(absolutePath));
}
public void addFiles(List<Path> absolutePathList) throws Exception {
// Проверяем существует ли zip файл
if (!Files.isRegularFile(zipFile)) {
throw new WrongZipFileException();
}
// Создаем временный файл
Path tempZipFile = Files.createTempFile(null, null);
List<Path> archiveFiles = new ArrayList<>();
try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(tempZipFile))) {
try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile))) {
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
String fileName = zipEntry.getName();
archiveFiles.add(Paths.get(fileName));
zipOutputStream.putNextEntry(new ZipEntry(fileName));
copyData(zipInputStream, zipOutputStream);
zipInputStream.closeEntry();
zipOutputStream.closeEntry();
zipEntry = zipInputStream.getNextEntry();
}
}
// Архивируем новые файлы
for (Path file : absolutePathList) {
if (Files.isRegularFile(file))
{
if (archiveFiles.contains(file.getFileName()))
ConsoleHelper.writeMessage(String.format("Файл '%s' уже существует в архиве.", file.toString()));
else {
addNewZipEntry(zipOutputStream, file.getParent(), file.getFileName());
ConsoleHelper.writeMessage(String.format("Файл '%s' добавлен в архиве.", file.toString()));
}
}
else
throw new PathIsNotFoundException();
}
}
// Перемещаем временный файл на место оригинального
Files.move(tempZipFile, zipFile, StandardCopyOption.REPLACE_EXISTING);
}
public List<FileProperties> getFilesList() throws Exception {
// Проверяем существует ли zip файл
if (!Files.isRegularFile(zipFile)) {
throw new WrongZipFileException();
}
List<FileProperties> files = new ArrayList<>();
try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile))) {
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
// Поля "размер" и "сжатый размер" не известны, пока элемент не будет прочитан
// Давайте вычитаем его в какой-то выходной поток
ByteArrayOutputStream baos = new ByteArrayOutputStream();
copyData(zipInputStream, baos);
FileProperties file = new FileProperties(zipEntry.getName(), zipEntry.getSize(), zipEntry.getCompressedSize(), zipEntry.getMethod());
files.add(file);
zipEntry = zipInputStream.getNextEntry();
}
}
return files;
}
private void addNewZipEntry(ZipOutputStream zipOutputStream, Path filePath, Path fileName) throws Exception {
Path fullPath = filePath.resolve(fileName);
try (InputStream inputStream = Files.newInputStream(fullPath)) {
ZipEntry entry = new ZipEntry(fileName.toString());
zipOutputStream.putNextEntry(entry);
copyData(inputStream, zipOutputStream);
zipOutputStream.closeEntry();
}
}
private void copyData(InputStream in, OutputStream out) throws Exception {
byte[] buffer = new byte[8 * 1024];
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
}
taskKey="com.javarush.task.task31.task3110.big18"\n\nArchiver (18)
Ты отличный ученик, я немного подправил твой код, можешь использовать этот архиватор для архивации
в повседневной жизни. Если будет время и желание, попробуй добавить операцию изменения степени
сжатия архива!
Требования:
1. Архиватор готов.
Archiver (17)
Осталась ерунда. Добавить добавление файла в архив. Звучит подозрительно, но именно этим мы и
займемся. Добавление файлов похоже на удаление, мы создаем временный файл архив, переписываем в
него все содержимое старого архива и добавляем новые файлы. Потом заменяем старый файл архива
новым.
1. Добавь публичный метод void addFiles(List<Path> absolutePathList) throws Exception в класс
ZipFileManager, где absolutePathList – список абсолютных путей добавляемых файлов. Этот метод
должен:
1.1. Как обычно, бросать исключение WrongZipFileException, если файл архива не существует
1.2. Создать временный файл архива
1.3. Пройти по всем файлам оригинального архива, переписать каждый файл в новый архив,
добавить имя переписанного файла в какой-нибудь локальный список.
1.4. Пройтись по списку добавляемых файлов.
1.5. Для каждого файла проверить, есть ли он на диске и является ли он обычным файлом,
если что-то не так, кинь исключение PathIsNotFoundException()
1.6. Проверить, есть ли добавляемый файл уже в архиве (используй список из п.1.3). Такое
возможно, если пользователь уже когда-то добавлял его.
- Если файла нет в списке, добавь его в новый архив, выведи сообщение, что такой-то файл
добавлен в архив
- Если файл есть в списке, просто сообщи пользователю, что такой файл уже есть в архиве
1.7. Заменить оригинальный файл архива временным, в котором уже есть добавленные
файлы.
2. Добавь публичный метод void addFile(Path absolutePath) throws Exception в класс ZipFileManager,
реализуй его с помощью вызова метода addFiles(), аналогично тому, как мы это делали для
удаления файла.
3. Реализуй метод execute() класса ZipAddCommand: все как обычно, но не забудь спросить у
пользователя в какой архив и какой файл он хочет добавить, обработай исключение
PathIsNotFoundException, которое может кинуть метод addFile().
4. Запусти программу и проверить, что добавление файла теперь работает.
Archiver (16)
Пришло время что-нибудь удалить из архива. Архив очень хитрая штука, нельзя вот так просто взять и
удалить какой-то элемент внутри него.
Почему? Представь, что мы решили сами придумать свой алгоритм сжатия текста. Посмотрев исходный
текст, мы видим, что в нем часто встречается фраза "быть программистом круто". Мы можем в месте, где
второй, третий, N-ый раз встречается наша фраза сделать пометку, что тут была фраза, как в строке S
начиная с символа номер K и длиной N, а саму фразу удалить. Когда мы заменим много повторяющихся
фраз, текст заметно сократится, но станет нечитаемым для тех, кто не знаком с нашим алгоритмом сжатия.
Мы же этот текст сможем восстановить (разархивировать). А теперь представь, что нам нужно удалить
часть текста, на которую ссылались сжатые фрагменты. В такой ситуации, весь наш архив перестанет
иметь смысл. Вот почему нельзя просто так удалить часть архива. Это очень примерное описание
варианта архивации, в реальности все намного сложнее.
Поэтому, чтобы что-то удалить из архива, нужно создать новый архив, переписать в него все, кроме
удаляемых файлов, а потом заменить старый архив вновь созданным.
1. Добавь публичный метод для удаления файлов из архива void removeFiles(List<Path> pathList)
throws Exception в класс ZipFileManager. В pathList будет передаваться список относительных путей на
файлы внутри архива. Он должен:
1.1. Бросать исключение WrongZipFileException, если файл архива не существует.
1.2. Создать временный файл архива в директории по умолчанию с помощью метода createTempFile() класса Files.
1.3. Пройтись по всем файлам оригинального архива, проверить, есть ли текущий файл в списке
на удаление.
- Если файл есть в списке, вывести сообщение, что мы удалили файл с таким-то именем и
перейти к следующему файлу.
- Если файла нет в списке на удаление, переписать его в новый архив
1.4. Заменить оригинальный файл архива временным, в который мы записали нужные файлы.
Это нужно сделать с помощью метода move() класса Files
2. Добавь публичный метод void removeFile(Path path) throws Exception в класс ZipFileManager,
который будет вызывать метод removeFiles, создавая список из одного элемента. Это можно сделать с помощью
метода singletonList() класса Collections. Посмотри, как он работает.
3. Реализуй метод execute() класса ZipRemoveCommand, создав объект класса ZipFileManager,
спросив пользователя из какого архива и какой файл будем удалять, и вызвав метод removeFile().
Все остальное, как и в других командах. Исключение PathIsNotFoundException можно не ловить, т.к. метод
removeFile() не должен его кидать.
4. Запусти программу и проверить, что удаление файла из архива работает.
Archiver (15)
Пора попробовать что-нибудь распаковать. Для этого добавим публичный метод void extractAll(Path
outputFolder) throws Exception в класс ZipFileManager. Path outputFolder - это путь, куда мы будем
распаковывать наш архив. У тебя уже большой опыт работы с элементами архива и потоками. Так что, я
дам только подсказки по реализации этого метода, а тебе придется хорошенько подумать, как это все
сделать:
1. Проверь, есть ли zip файл вообще
2. Если директория outputFolder не существует, то ее нужно создать, как и все папки, внутри которых
она лежит.
3. Внутри архива некоторые файлы могут лежат внутри папок, тогда метод getName() элемента
архива ZipEntry, вернет не совсем имя, как может показаться из названия, а относительный путь
внутри архива. Этот относительный путь должен сохраниться и после распаковки, но уже
относительно той директории, куда мы распаковали архив
4. Реализуй метод execute() класса ZipExtractCommand, по аналогии с таким же методом класса
ZipCreateCommand, сделай такой же блок try-catch, только поменяй сообщения выводимые
пользователю, чтобы он понял, что сейчас мы будем распаковывать архив, и что нужно ввести
полное имя архива и директорию, куда будем распаковывать. Не забудь вызвать метод extractAll
класса ZipFileManager, а не createZip, как это было в ZipCreateCommand
5. Запускай программу и наслаждайся результатом распаковки
Примечание:
Для получения потоков чтения и записи используй Files.newInputStream(Path path), Files.newOutputStream(Path path).
Archiver (14)
Все готово, чтобы реализовать метод execute() класса ZipContentCommand:
1. Выведи сообщение "Просмотр содержимого архива."
2. Создай объект класса ZipFileManager с помощью метода getZipFileManager()
3. Выведи сообщение "Содержимое архива:"
4. Получи список файлов архива с помощью метода getFilesList()
5. Выведи свойства каждого файла в консоль. Тут нам и пригодится ранее реализованный метод
toString() класса FileProperties
6. Выведи сообщение "Содержимое архива прочитано."
7. Запусти программу и проверь, что команда "просмотреть содержимое архива" работает
Archiver (13)
Продолжим наш путь к получению содержимого файла архива. Напишем метод getFilesList() в классе
ZipFileManager. Он будет возвращать список файлов в архиве, вернее список свойств этих файлов (класс
свойств FileProperties мы уже реализовали). Итак:
1. Добавь метод List<FileProperties> getFilesList() throws Exception в класс ZipFileManager
2. Внутри метода проверь является ли содержимое zipFile обычным файлом с помощью
подходящего метода класса Files. Если это не файл, брось исключение WrongZipFileException().
3. Создай список с элементами типа FileProperties, в него мы будем складывать свойства файлов
4. Создай входящий поток ZipInputStream, для файла из переменной zipFile. Как и в прошлые разы, оберни его создание
в try-with-resources
5. Пройдись по всем элементам ZipEntry потока ZipInputStream
6. Для каждого элемента ZipEntry вычитай его содержимое, иначе у нас не будет информации о его
размере. Нельзя узнать размер файла в архиве, не вычитав его. Это очень легко сделать с
помощью функции copyData, используя временный буфер типа ByteArrayOutputStream.
7. Получи имя, размер, сжатый размер и метод сжатия элемента архива. Посмотри, что еще можно
узнать о нем.
8. Создай объект класса FileProperties, используя полученные данные о файле.
9. Добавь созданный объект из п.8 в список из п.3
10. После выхода из цикла верни собранную информацию вызвавшему методу.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment