Java 无法从InputStream创建zip文件
我需要从输入流数据创建一个zip文件,在写入zip之前,我需要找到输入流的校验和 为此,我使用以下代码:Java 无法从InputStream创建zip文件,java,inputstream,checksum,outputstream,Java,Inputstream,Checksum,Outputstream,我需要从输入流数据创建一个zip文件,在写入zip之前,我需要找到输入流的校验和 为此,我使用以下代码: private String writeZipFileToFS(List<ResponsePacks> attachmentList) throws IOException { File fileToWrite = new File(getZipPath() + "fileName.zip"); try
private String writeZipFileToFS(List<ResponsePacks> attachmentList) throws IOException
{
File fileToWrite = new File(getZipPath() + "fileName.zip");
try
{
FileUtils.copyInputStreamToFile(compress(attachmentList), fileToWrite);
}
catch (IOException e)
{
throw e;
}
return fileName;
}
private InputStream compress(List<ResponsePacks> attachmentList)
{
byte buffer[] = new byte[2048];
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ZipOutputStream zipFileToSend = new ZipOutputStream(byteStream);
try
{
for (ResponsePacks info : attachmentList)
{
// only for successful requests files would need to be added
zipFileToSend.putNextEntry(new ZipEntry(info.getFileName()));
InputStream in = info.getFileContentStream();
getCheckSum(in, info.getFileName());
int length;
while ((length = in.read(buffer)) >= 0)
{
zipFileToSend.write(buffer, 0, length);
}
zipFileToSend.closeEntry();
}
zipFileToSend.close();
}
catch (IOException e)
{
throw e;
}
return new ByteArrayInputStream(byteStream.toByteArray());
}
private static void getCheckSum(InputStream is, String fileName)
{
byte[] dataCopy = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try
{
IOUtils.copy(is, outputStream);
dataCopy = outputStream.toByteArray();
printLog("Byte Array Size {}", dataCopy.length);
String checkSum = calculateChecksum(dataCopy);
printLog("Checksum for file {} {}", fileName, checkSum);
outputStream.flush();
outputStream.close();
}
catch (Exception e)
{
printLog("Error on calculationg checksum {}", e.getMessage());
}
}
private static String calculateChecksum(byte[] dataCopy)
{
try (ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(dataCopy)))
{
ZipEntry zipEntry;
MessageDigest digest = DigestUtils.getSha256Digest();
DWriter writer = new DWriter(digest);
while ((zipEntry = zipInputStream.getNextEntry()) != null)
{
byte[] entityData = IOUtils.toByteArray(zipInputStream);
if (!zipEntry.isDirectory())
{
writer.write(entityData);
}
}
if (writer.getChecksum() != null)
{
return writer.getChecksum();
}
}
catch (Exception e)
{
throw e;
}
return "";
}
static class DWriter
{
private final MessageDigest myDigest;
DWriter(MessageDigest digest)
{
myDigest = digest;
}
public void write(byte[] data)
{
myDigest.update(data);
}
public String getChecksum()
{
return new String(Hex.encodeHex(myDigest.digest()));
}
}
我找不到哪里做错了,因为zip文件是用空内容创建的,校验和也总是创建相同的内容
请求帮助我找到我做错的地方。您使用了两次相同的inputstream:首先读取它以获得校验和,然后再次读取它以写入zip条目
getCheckSum(in, info.getFileName());
int length;
while ((length = in.read(buffer)) >= 0)
{
zipFileToSend.write(buffer, 0, length);
}
当你第二次尝试阅读时,已经没有东西可读了,所以没有东西被写入zip条目
getCheckSum(in, info.getFileName());
int length;
while ((length = in.read(buffer)) >= 0)
{
zipFileToSend.write(buffer, 0, length);
}
一些输入流可以被重置并多次读取,如果不是这种情况,您需要将数据保存到
ByteArrayOutputStream
(正如您在getCheckSum()方法中已经做的那样),然后,您可以多次读取该数据。事实上,您正在吞咽任何IOException并继续进行,就好像它们没有发生一样,这很可能与此有关。(calculateChecksum中也是如此)。在不记录异常的情况下接受异常几乎总是一个坏主意。我建议您停止这样做作为第一步,看看是否有帮助。特定的校验和值是空字符串的SHA-256散列,请参阅。此外,您可以更改设计,使校验和计算成为流处理函数,因此它消耗流,然后进行计算,同时产生一个不变的流,这将成为下一阶段的输入。如果当前的架构是一个流处理管道,那么这可能是有意义的better@Guillaume我修改了我的设计,而不是读取两次相同的inputstream,我正在读取一次,并在同一个循环中计算校验和,从而解决了我的第一个问题,即现在zip正在使用适当的内容创建,但我仍然无法解决我的第二个问题,即校验和总是为空字符串创建,请检查此项