conflux
conflux copied to clipboard
zip stream created by conflux cannot be parsed by Java (java.util.zip)
I need to upload a directory (of files) to server, so I
- pack user-selected directory as zip stream with conflux
- upload the zip stream to server end by fetch upload streaming
- unpack the zip stream at server end with java.util.zip
Then I did an integration test, and I got a problem:
-
The server side throwed an error/exception which says
java.util.zip.ZipException: only DEFLATED entries can have EXT descriptor
But for STORE zip file created by 7Zip, its stream can be successfully parsed by Java (java.util.zip)
By the way, I created a java unit test to reproduce the error, see code below. conflux.zip standands for a zip file created with conflux 7zip.zip standands for a zip file created with 7Zip using STORE method
ZipTest.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributeView;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.junit.Test;
public class ZipTest {
@Test
public void unpackZip() {
//XXX conflux.zip 7zip.zip
File inputFile=new File(System.getProperty("user.home"), "Downloads"+File.separator+"conflux.zip");
File outputDir=new File(inputFile.getPath().replaceFirst("\\.zip$", ""));
try(FileInputStream input=new FileInputStream(inputFile)){
ZipTest.unpack(input, outputDir);
}catch(IOException e){
e.printStackTrace();
}
}
public static void unpack(InputStream input, File outputDir) throws IOException {
boolean setFileTimes=true;
boolean doNameCheck=false;
outputDir.mkdirs();
ArrayList<File> dirs=new ArrayList<File>();
ArrayList<ZipEntry> entries=new ArrayList<ZipEntry>();
byte[] buffer=new byte[8192];
try(ZipInputStream zipInput=new ZipInputStream(input);){
for(ZipEntry entry=zipInput.getNextEntry(); entry!=null; entry=zipInput.getNextEntry()){
System.out.println(entry.getName()); //XXX
if(doNameCheck){
// TODO checkEntryPath(entry.getName());
}
File file=new File(outputDir, entry.getName()).getCanonicalFile();
if(entry.isDirectory()){
if(!file.exists() && !file.mkdir()){
throw new IOException("Failed to mkdir "+entry.getName());
}
if(setFileTimes){
// Note: directory's file time should be set later, from inner to outer
dirs.add(file);
entries.add(entry);
}
}else{
File parentFile=file.getParentFile();
// TODO ensureParentDirectories(parentFile);
try(FileOutputStream output=new FileOutputStream(file)){
int len;
while ((len = zipInput.read(buffer)) > 0) {
output.write(buffer, 0, len);
}
}
if(setFileTimes){
Files.getFileAttributeView(file.toPath(), BasicFileAttributeView.class)
.setTimes(entry.getLastModifiedTime(), entry.getLastAccessTime(), entry.getCreationTime());
}
}
}
zipInput.closeEntry();
if(setFileTimes){
for(int i=dirs.size()-1; i>=0; i--){
File dir=dirs.get(i);
ZipEntry entry=entries.get(i);
Files.getFileAttributeView(dir.toPath(), BasicFileAttributeView.class)
.setTimes(entry.getLastModifiedTime(), entry.getLastAccessTime(), entry.getCreationTime());
}
}
}
}
}