The problem of disordered directory structure of DotNet unzip zip file under Mac

Keywords: Mac Java Windows Linux

Extracting a file under Dot Net is very simple:

ZipFile.ExtractToDirectory("test.zip", "./test");

However, when a program runs the Dot Net program on Mac to extract a zip file, the directory structure is gone, as shown in the following figure:

image.png

After some research, it is found that the reason is that the zip is generated by the java.util.zip compression method of Java. The compressed directory uses File.separator to splice the directory name, and the program runs under Windows. As a result, the symbol is not recognized when decompressed under mac or linux, and the directory ID is regarded as a character of the file name.

The solution is simple. Just change File.separator to / directly. By the way, I tried to use the compression tool with Windows operating system and the zip compressed by 7zip to decompress under Mac without this problem.

Finally, the modified Java compression code is attached:

public ZipCompressor(File i, File o) {
        source = i;
        if (!source.exists()) { throw new RuntimeException(i + " : has not been found"); }
        target = o;
    }
    
    public void execute() {
        try {
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(target));
            compress(source, out, "");
            out.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    private void compress(File file, ZipOutputStream out, String basedir) {
        if (file.isDirectory()) {
            this.compressD(file, out, basedir);
        } else {
            this.compressF(file, out, basedir);
        }
    }
    
    private void compressD(File dir, ZipOutputStream out, String basedir) {
        if (!dir.exists()) return;
        
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            compress(files[i], out, basedir + dir.getName() + "/");
        }
    }
    
    private void compressF(File file, ZipOutputStream out, String basedir) {
        if (!file.exists()) { return; }
        try {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            ZipEntry entry = new ZipEntry(basedir + file.getName());
            out.putNextEntry(entry);
            int count;
            byte data[] = new byte[BUFFER];
            while ((count = bis.read(data, 0, BUFFER)) != -1) {
                out.write(data, 0, count);
            }
            bis.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

Posted by geo3d on Thu, 02 Apr 2020 04:33:08 -0700