|
| 1 | + |
| 2 | +//That was the true Light, which lighteth every man that cometh into the world. (John 1:9) |
| 3 | + |
| 4 | +package com.javarush.task.task31.task3110.command; |
| 5 | + |
| 6 | +import com.javarush.task.task31.task3110.ConsoleHelper; |
| 7 | + |
| 8 | +public class ExitCommand implements Command { |
| 9 | + |
| 10 | + @Override |
| 11 | + public void execute() throws Exception { |
| 12 | + ConsoleHelper.writeMessage("До встречи!"); |
| 13 | + } |
| 14 | +} |
| 15 | + |
| 16 | +/* |
| 17 | +Archiver (4) |
| 18 | +
|
| 19 | +Каждая команда подразумевает выполнение каких-то действий. Создадим интерфейс Command, с |
| 20 | +
|
| 21 | +методом execute() (execute - "выполнить" по-английски). Для каждой команды мы создадим свой собственный класс. Все классы команд должны реализовывать (быть унаследованы) интерфейс Command. |
| 22 | +
|
| 23 | +Так как команд будет много, отведем для них отдельный пакет command. Все интерфейсы и реализации команд будем хранить именно в нем. |
| 24 | +
|
| 25 | +Самая простая команда - это выход EXIT, с нее и начнем. |
| 26 | +
|
| 27 | +1. Создай пакет command |
| 28 | +
|
| 29 | +2. В нем объявить интерфейс Command |
| 30 | +
|
| 31 | +3. Добавь метод void execute() throws Exception в интерфейс Command |
| 32 | +
|
| 33 | +4. Объяви класс ExitCommand, реализующий интерфейс Command |
| 34 | +
|
| 35 | +5. Реализуй метод execute() в классе ExitCommand, он должен выводить "До встречи!" с помощью |
| 36 | +
|
| 37 | +метода из класса ConsoleHelper |
| 38 | +
|
| 39 | +6. В самом конце метода main в класса Archiver добавь код, который создает объект типа ExitCommand и вызывает у него метод execute() |
| 40 | +
|
| 41 | +7. Попробуй, как это все работает |
| 42 | +
|
| 43 | +Обрати внимание, что все файлы проекта должны быть в кодировке UTF-8. Кодировку в IntelliJ IDEA можно задать через пункты меню Settings -> Editor -> File Encodings. Проверь, что все три поля отвечающие за кодировку выставлены в UTF-8. |
| 44 | +
|
| 45 | +
|
| 46 | +
|
| 47 | +
|
| 48 | +
|
| 49 | +Требования: |
| 50 | +
|
| 51 | +1. В пакете command должен быть создан интерфейс Command. |
| 52 | +
|
| 53 | +2. В Command должен быть объявлен метод void execute() throws Exception. |
| 54 | +
|
| 55 | +3. Создай класс ExitCommand в пакете command. Он должен реализовывать Command. |
| 56 | +
|
| 57 | +4. Метод execute в классе ExitCommand должен выводить в консоль "“До встречи!”" с использованием ConsoleHelper. |
| 58 | +
|
| 59 | +5. В конце main нужно добавить создание объекта ExitCommand и вызов у него метода execute. |
| 60 | +
|
| 61 | +Archiver (3) |
| 62 | +
|
| 63 | +Как видишь, архивировать оказалось не так уж и сложно. Но наш архиватор получился каким-то уж |
| 64 | +
|
| 65 | +слишком примитивным. Настоящий архиватор должен уметь гораздо больше: распаковку архива, |
| 66 | +
|
| 67 | +добавление нового файла в существующий архив, удаление файла из архива, просмотр содержимого |
| 68 | +
|
| 69 | +архива. Сейчас мы будем улучшать наш архиватор. А для этого придется написать несколько новых |
| 70 | +
|
| 71 | +классов. Сначала давай создадим enum Operation, который будет содержать все команды, которые |
| 72 | +
|
| 73 | +поддерживает наш архиватор. |
| 74 | +
|
| 75 | +Так же было бы удобно использовать ConsoleHelper для работы с консолью, чтобы все что касается |
| 76 | +
|
| 77 | +консоли было собрано в одном классе. В дальнейшем, если не указано обратного, то весь ввод и вывод должен происходить через ConsoleHelper. |
| 78 | +
|
| 79 | +
|
| 80 | +
|
| 81 | +1. Объяви enum Operation, в него добавить команды: |
| 82 | +
|
| 83 | +1.1. Создать архив CREATE |
| 84 | +
|
| 85 | +1.2. Добавить файл в архив ADD |
| 86 | +
|
| 87 | +1.3. Удалить файл из архива REMOVE |
| 88 | +
|
| 89 | +1.4. Извлечь содержимое архива EXTRACT |
| 90 | +
|
| 91 | +1.5. Просмотреть содержимое архива CONTENT |
| 92 | +
|
| 93 | +1.6. Выйти из программы EXIT |
| 94 | +
|
| 95 | +2. Создай класс ConsoleHelper и реализуй в нем статические публичные методы: |
| 96 | +
|
| 97 | +2.1. Вывести сообщение в консоль void writeMessage(String message) |
| 98 | +
|
| 99 | +2.2. Прочитать строку с консоли String readString() |
| 100 | +
|
| 101 | +2.3. Прочитать число с консоли int readInt() |
| 102 | +
|
| 103 | +Методы чтения с консоли могут бросать исключение IOException в случае ошибки ввода, учти |
| 104 | +
|
| 105 | +это при их объявлении. |
| 106 | +
|
| 107 | +
|
| 108 | +
|
| 109 | +Archiver (2) |
| 110 | +
|
| 111 | +Сейчас мы напишем реализацию метода createZip(Path source), в котором мы будем архивировать файл, заданный переменной source. |
| 112 | +
|
| 113 | +В Java есть специальный класс ZipOutputStream из пакета java.util.zip, который сжимает (архивирует) |
| 114 | +
|
| 115 | +переданные в него данные. Чтобы несколько файлов, сжимаемые в один архив, не слиплись вместе, для каждого из них создается специальная сущность - элемент архива ZipEntry. Т.е. в ZipOutputStream мы сначала кладем ZipEntry, а затем уже записываем содержимое файла. При записи файл автоматически сжимается, а при чтении - автоматически восстанавливается. ZipEntry может быть не только файлом, но и папкой. |
| 116 | +
|
| 117 | +
|
| 118 | +
|
| 119 | +Чтобы заархивировать файл (создать новый архив и добавить в него файл): |
| 120 | +
|
| 121 | +1. Создай новый поток архива ZipOutputStream используя переменную класса zipFile, с помощью метода newOutputStream класса Files. |
| 122 | +
|
| 123 | +2. Создай новый элемент архива ZipEntry. В конструктор ZipEntry передай строку, содержащую имя новой записи. Имя нужно получить из полного пути source, взять только имя файла и сконвертировать его в String. |
| 124 | +
|
| 125 | +3. Добавь в поток архива созданный элемент архива. |
| 126 | +
|
| 127 | +4. Перепиши данные из файла, который архивируем в поток архива. Для этого: |
| 128 | +
|
| 129 | +4.1. Создай поток InputStream для добавляемого файла source, используя метод newInputStream класса Files |
| 130 | +
|
| 131 | +4.2. Сделай цикл, который будет читать данные из InputStream (созданного в п.4.1), пока они там есть и записывать их в ZipOutputStream (созданный в п.1) |
| 132 | +
|
| 133 | +4.3. Закрой InputStream, сделай это с помощью try-with-resources |
| 134 | +
|
| 135 | +5. Закрой элемент архива у потока архива |
| 136 | +
|
| 137 | +6. Закрой поток архива, сделай это также с помощью try-with-resources |
| 138 | +
|
| 139 | +7. Запусти программу и проверь, что файл архивируется |
| 140 | +
|
| 141 | +
|
| 142 | +
|
| 143 | +Archiver (1) |
| 144 | +
|
| 145 | +Давай напишем архиватор. Архиватор, как минимум, должен уметь архивировать и разархивировать |
| 146 | +
|
| 147 | +файлы. |
| 148 | +
|
| 149 | +
|
| 150 | +
|
| 151 | +Начнем с первого. |
| 152 | +
|
| 153 | +Нам потребуется менеджер архива. Он будет совершать операции над файлом архива (файлом, который будет храниться на диске и иметь расширение zip). Класс, который будет этим заниматься, назовем ZipFileManager. А главный класс приложения "Архиватор" будет называться Archiver. |
| 154 | +
|
| 155 | +В программировании и не только, есть понятие полного (абсолютного) и относительного пути. Для начала, разберемся что-же такое путь вообще. Путь (англ. Path) - это набор символов, который показывает, где в операционной системе находится какой-то файл или папка. |
| 156 | +
|
| 157 | +Полный или абсолютный путь - это путь, начинающийся с корневой директории. В операционной системе Windows, корневой директорией принято считать диск. |
| 158 | +
|
| 159 | +Пример полного пути в Windows: C:userzipsTest1.zip. |
| 160 | +
|
| 161 | +Относительный путь - это путь относительно какой-то директории. zipsTest1.zip - это пример |
| 162 | +
|
| 163 | +относительного пути файла Test1.zip относительно директории (папки) C:user. Относительный путь, |
| 164 | +
|
| 165 | +относительно директории C:userzips будет просто Test1.zip и совпадать с именем файла. |
| 166 | +
|
| 167 | +Обрати внимание, что по умолчанию, и полный, и относительный путь к файлу, включают в себя имя |
| 168 | +
|
| 169 | +файла. |
| 170 | +
|
| 171 | +1. Создай класс менеджер ZipFileManager |
| 172 | +
|
| 173 | +2. Добавь в класс приватную переменную Path zipFile. В ней мы будем хранить полный путь к архиву, с которым будем работать. |
| 174 | +
|
| 175 | +3. Добавь конструктор ZipFileManager(Path zipFile). Проинициализируй поле класса zipFile. |
| 176 | +
|
| 177 | +4. Объяви публичный метод createZip(Path source) throws Exception, пока с пустой реализацией. |
| 178 | +
|
| 179 | +Path source - это путь к чему-то, что мы будем архивировать. |
| 180 | +
|
| 181 | +5. Создай класс Archiver и добавь в него метод main. |
| 182 | +
|
| 183 | +6. В методе main: |
| 184 | +
|
| 185 | +6.1 Запроси пользователя ввести полный путь архива с клавиатуры. Не забудь, что имя тоже входит в состав полного пути. |
| 186 | +
|
| 187 | +6.2 Создай объект класса ZipFileManager, передав в него имя файла архива. Разберись, как из String получить Path. |
| 188 | +
|
| 189 | +
|
| 190 | +
|
| 191 | +Подсказка: изучи метод get() класса Paths. |
| 192 | +
|
| 193 | +
|
| 194 | +
|
| 195 | +6.3 Запроси пользователя ввести путь к файлу, который будем архивировать. Не путай это с файлом архива, который мы уже ввели. На этот раз нам нужен файл, который мы будем сжимать, а не в котором хранить сжатые данные. |
| 196 | +
|
| 197 | +6.4 Вызови метод createZip у объекта ZipFileManager, передав в него путь для архивации. |
| 198 | +*/ |
0 commit comments