gpt4 book ai didi

java - 如何在 Java 中的 ZIP 文件内创建 ZIP 文件

转载 作者:行者123 更新时间:2023-11-30 06:25:28 28 4
gpt4 key购买 nike

我正在尝试在 ZIP 文件内创建一个 ZIP 文件,以重新构建我在 Java 中获得的先前内存中的 zip 结构。

我失败了,因为我在初始 ZIP 文件内创建的内部 ZIP 上收到错误。文件已损坏。尝试打开文件时,我收到“文件意外结束”

我得到了这个结构:

-输入.zip--innerInput.zip

代码使用 java Stack 和 Map 将其全部解压到内存中。然后它创建 input2.zip,其中包含 innerInput.zip。

摘要:我需要创建一个包含 ZIP 的 ZIP,所有内容都在内存中(暂时不保存在磁盘上)。

代码:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.lang3.StringUtils;

public class ZipHandler1 {

private static final int BUFFER_SIZE = 2048;

private static final String ZIP_EXTENSION = ".zip";
public static final Integer FOLDER = 1;
public static final Integer ZIP = 2;
public static final Integer FILE = 3;


public static Deque<Map<Integer, Object[]>> unzip(ByteArrayOutputStream zippedOutputFile) {

try {

ZipInputStream inputStream = new ZipInputStream(
new BufferedInputStream(new ByteArrayInputStream(
zippedOutputFile.toByteArray())));

ZipEntry entry;

Deque<Map<Integer, Object[]>> result = new ArrayDeque<Map<Integer, Object[]>>();

while ((entry = inputStream.getNextEntry()) != null) {

LinkedHashMap<Integer, Object[]> map = new LinkedHashMap<Integer, Object[]>();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
System.out.println("\tExtracting entry: " + entry);
int count;
byte[] data = new byte[BUFFER_SIZE];
if (!entry.isDirectory()) {
BufferedOutputStream out = new BufferedOutputStream(
outputStream, BUFFER_SIZE);

while ((count = inputStream.read(data, 0, BUFFER_SIZE)) != -1) {
out.write(data, 0, count);
}

out.flush();
out.close();

// recursively unzip files
if (entry.getName().toUpperCase().endsWith(ZIP_EXTENSION.toUpperCase())) {
map.put(ZIP, new Object[] {entry.getName(), unzip(outputStream)});
result.add(map);

} else {
map.put(FILE, new Object[] {entry.getName(), outputStream});
result.add(map);
}
} else {
map.put(FOLDER, new Object[] {entry.getName(),
unzip(outputStream)});
result.add(map);
}
}

inputStream.close();

return result;

} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

package course.hernan;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;

public class FileReader {

private static final int BUFFER_SIZE = 2048;

public static void main(String[] args) {

try {
File f = new File("DIR/inputs.zip");
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(baos);
byte[] buffer = new byte[BUFFER_SIZE];

while (bis.read(buffer, 0, BUFFER_SIZE) != -1) {
bos.write(buffer);
}

bos.flush();
bos.close();
bis.close();

Deque<Map<Integer, Object[]>> outputDataStack = ZipHandler1.unzip(baos);

//Output file
File fout = new File("DIR/inputs2.zip");

ZipOutputStream zipOutput = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(fout)));

processZip(outputDataStack, zipOutput);
zipOutput.close();

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private static final void processZip(Deque<Map<Integer, Object[]>> outputDataStack,
ZipOutputStream zipOutput) throws IOException {

while (!outputDataStack.isEmpty()) {
Map<Integer, Object[]> map = outputDataStack.pop();

for (Map.Entry<Integer, Object[]> entry : map.entrySet()) {
System.out.println("KEY:" + entry.getKey());
Object[] values = entry.getValue();
String entryName = (String)values[0];

if (entry.getKey().equals(ZipHandler1.FILE)) {
System.out.println("..........................");
System.out.println("type: FILE");
System.out.println("Name: " + entryName);

zipOutput.putNextEntry(new ZipEntry(entryName));
byte[] outputByteArray = ((ByteArrayOutputStream)values[1]).toByteArray();

IOUtils.write(outputByteArray, zipOutput);
zipOutput.closeEntry();
((ByteArrayOutputStream)values[1]).close();

} else if (entry.getKey().equals(ZipHandler1.FOLDER)) {
System.out.println("..........................");
System.out.println("type: FOLDER");
System.out.println("Name: " + entryName);

zipOutput.putNextEntry(new ZipEntry(entryName));
System.out.println("..........................");
zipOutput.closeEntry();

} else if (entry.getKey().equals(ZipHandler1.ZIP)) {
System.out.println("..........................");
System.out.println("type: ZIP");
System.out.println("Name: " + entryName);

zipOutput.putNextEntry(new ZipEntry(entryName));

ByteArrayOutputStream innerZipByteArray = new ByteArrayOutputStream(BUFFER_SIZE);
ZipOutputStream innerZipOutput = new ZipOutputStream(
new BufferedOutputStream(innerZipByteArray));

processZip((Deque<Map<Integer,Object[]>>)values[1], innerZipOutput);
innerZipOutput.flush();
IOUtils.write(zzzz.toByteArray(), zipOutput);
innerZipOutput.close();
zipOutput.closeEntry();
System.out.println("..........................");
}
System.out.println("..........................");
zipOutput.closeEntry();
}
}
}

最佳答案

谢谢我!

这个答案对我来说很难找到,但对其他人来说可能是显而易见的。

简短回答:我太快关闭了内部 ZIP 流

好的,问题是在 ZIP 中存储 ZIP,对吗?好吧,我收到一个错误,因为内部 zipper 关闭得太快

解决方案:

像这样创建内部 zip 文件: ByteArrayOutputStream innerZipBufferOutput = new ByteArrayOutputStream(BUFFER_SIZE); ZipOutputStream 内部ZipOutput = 新的ZipOutputStream( 新的 BufferedOutputStream(innerZipBufferOutput));

将字节(信息)写入内部 zip

关闭内部 zip 流 innerZipOutput.close(); **这是我在错误的时间关闭*

此时字节形式的数据位于innerZipBufferOutput

在外部 zip 文件中设置内部 zip 文件的条目

ZipEntry newEntry = new ZipEntry(entryName);
zipOutput.putNextEntry(newEntry);

将内 zipper 写入外 zipper

zipOutput.write(innerZipBufferOutputByteArray);

关闭外 zipper

zipOutput.flush();
zipOutput.closeEntry();

瞧!

示例(代码摘录)-- 你有一个 ZipOutputStream(外部 zip 文件)

ByteArrayOutputStream innerZipBufferOutput = new ByteArrayOutputStream(BUFFER_SIZE);
ZipOutputStream innerZipOutput = new ZipOutputStream(new BufferedOutputStream(innerZipBufferOutput));

<<process - e.g. create your inner zip file>>

innerZipOutput.flush();
innerZipOutput.close();

ZipEntry newEntry = new ZipEntry(<<your entry name>>);

zipOutput.setMethod(ZipOutputStream.STORED);

byte[] innerZipBufferOutputByteArray = innerZipBufferOutput.toByteArray();

//Create the nested ZIP inside the outer ZIP
ZipEntry newEntry = new ZipEntry(entryName);
zipOutput.putNextEntry(newEntry);

zipOutput.write(innerZipBufferOutputByteArray);


zipOutput.closeEntry();
zipOutput.close();

关于java - 如何在 Java 中的 ZIP 文件内创建 ZIP 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47298015/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com