Есть ли какой-нибудь пример кода, как particaly распаковать папку из ZIP в мой желаемый каталог? Я прочитал все файлы из папки "FOLDER" в массив байтов, как мне воссоздать из его файловой структуры?
Java ZIP - как распаковать папку?
Ответ 1
Я не уверен, что вы подразумеваете под частично? Вы имеете в виду сделать это самостоятельно без помощи API?
В случае, если вы не возражаете против использования библиотеки с открытым исходным кодом, для этого есть крутой API под названием zip4J
Это простой в использовании, и я думаю, что есть хорошие отзывы об этом. Посмотрите этот пример:
String source = "folder/source.zip";
String destination = "folder/source/";
try {
ZipFile zipFile = new ZipFile(source);
zipFile.extractAll(destination);
} catch (ZipException e) {
e.printStackTrace();
}
Если файлы, которые вы хотите разархивировать, имеют пароли, вы можете попробовать это:
String source = "folder/source.zip";
String destination = "folder/source/";
String password = "password";
try {
ZipFile zipFile = new ZipFile(source);
if (zipFile.isEncrypted()) {
zipFile.setPassword(password);
}
zipFile.extractAll(destination);
} catch (ZipException e) {
e.printStackTrace();
}
Я надеюсь, что это полезно.
Ответ 2
Вот код, который я использую. Измените BUFFER_SIZE для своих нужд.
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public final class ZipUtils {
private static final int BUFFER_SIZE = 4096;
public static void extract(ZipInputStream zip, File target) throws IOException {
try {
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
File file = new File(target, entry.getName());
if (!file.toPath().normalize().startsWith(target.toPath())) {
throw new IOException("Bad zip entry");
}
if (entry.isDirectory()) {
file.mkdirs();
continue;
}
byte[] buffer = new byte[BUFFER_SIZE];
file.getParentFile().mkdirs();
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
int count;
while ((count = zip.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
out.close();
}
} finally {
zip.close();
}
}
}
Ответ 3
То же самое можно достичь, используя библиотеку Ant Compress. Он сохранит структуру папок.
Зависимость от Maven: -
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-compress</artifactId>
<version>1.2</version>
</dependency>
Пример кода: -
Unzip unzipper = new Unzip();
unzipper.setSrc(theZIPFile);
unzipper.setDest(theTargetFolder);
unzipper.execute();
Ответ 4
Здесь простое решение, которое следует более современным соглашениям. Вы можете изменить размер буфера, чтобы быть меньше, если вы разархивируете большие файлы. Это значит, что вы не храните всю информацию о файлах в памяти.
public static void unzip(File source, String out) throws IOException {
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source))) {
ZipEntry entry = zis.getNextEntry();
while (entry != null) {
File file = new File(out, entry.getName());
if (entry.isDirectory()) {
file.mkdirs();
} else {
File parent = file.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) {
byte[] buffer = new byte[Math.toIntExact(entry.getSize())];
int location;
while ((location = zis.read(buffer)) != -1) {
bos.write(buffer, 0, location);
}
}
}
entry = zis.getNextEntry();
}
}
}
Ответ 5
Вот более "современный" полный код, основанный на этом посте, но с рефакторингом (и с использованием Lombok
):
import lombok.var;
import lombok.val;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipInputStream;
import static java.nio.file.Files.createDirectories;
public class UnZip
{
public static void unZip(String sourceZipFile, String outputDirectory) throws IOException
{
val folder = new File(outputDirectory);
createDirectories(folder.toPath());
try (val zipInputStream = new ZipInputStream(new FileInputStream(sourceZipFile, Charset.forName("Cp437"))))
{
var nextEntry = zipInputStream.getNextEntry();
while (nextEntry != null)
{
val fileName = nextEntry.getName();
val newFile = new File(outputDirectory + File.separator + fileName);
newFile.getParentFile().mkdirs();
if(fileName.endsWith("/")){
newFile.mkdirs();
} else {
writeFile(zipInputStream, newFile);
}
writeFile(zipInputStream, newFile);
nextEntry = zipInputStream.getNextEntry();
}
zipInputStream.closeEntry();
}
}
private static void writeFile(ZipInputStream inputStream, File file) throws IOException
{
val buffer = new byte[1024];
file.createNewFile();
try (val fileOutputStream = new FileOutputStream(file))
{
int length;
while ((length = inputStream.read(buffer)) > 0)
{
fileOutputStream.write(buffer, 0, length);
}
}
}
}
Ответ 6
Вы должны получить все записи из вашего почтового файла:
Enumeration entries = zipFile.getEntries();
Затем итерируя по этому перечислению, возьмите ZipEntry
из него, проверьте, является ли он каталогом или нет, и создайте каталог или просто извлеките файл соответственно.