Adding files to ZIP file
Asked Answered
H

3

2

I am trying to add some files to a ZIP file, it creates the file but does not add anything into it. Code 1:

String fulldate = year + "-" + month + "-" + day + "-" + min;

File dateFolder = new File("F:\\" + compname + "\\" + fulldate);
dateFolder.mkdir();

String zipName = "F:\\" + compname + "\\" + fulldate + "\\" + fulldate + ".zip";

zipFolder(tobackup, zipName);

My function:

public static void zipFolder(File folder, String name) throws Exception {
    byte[] buffer = new byte[18024];

    ZipOutputStream out = new ZipOutputStream(new FileOutputStream(name));
    FileInputStream in = new FileInputStream(folder);

    out.putNextEntry(new ZipEntry(name));

    int len;

    while((len = in.read(buffer)) > 0) {
        out.write(buffer, 0, len);
    }

    out.closeEntry();
    in.close();
    out.close();
}

Edit: I found the problem, it was just having trouble writing files from the C:\ drive into a ZIP in the F:\ drive

Hexahydrate answered 11/4, 2012 at 10:7 Comment(1)
If you want to iterate over the files in the given folder, use the listFiles()-method of your File-object.Pullen
A
15

You can't zip folders, only files. To zip folders, you have to add all the subfiles manually. I wrote this class that does the job. You can have it for free :)

The usage would be this:

List<File> sources = new ArrayList<File>();
sources.add(tobackup);
Packager.packZip(new File(zipName), sources);

Here is the class:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Packager
{
    public static void packZip(File output, List<File> sources) throws IOException
    {
        System.out.println("Packaging to " + output.getName());
        ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(output));
        zipOut.setLevel(Deflater.DEFAULT_COMPRESSION);

        for (File source : sources)
        {
            if (source.isDirectory())
            {
                zipDir(zipOut, "", source);
            } else
            {
                zipFile(zipOut, "", source);
            }
        }
        zipOut.flush();
        zipOut.close();
        System.out.println("Done");
    }

    private static String buildPath(String path, String file)
    {
        if (path == null || path.isEmpty())
        {
            return file;
        } else
        {
            return path + "/" + file;
        }
    }

    private static void zipDir(ZipOutputStream zos, String path, File dir) throws IOException
    {
        if (!dir.canRead())
        {
            System.out.println("Cannot read " + dir.getCanonicalPath() + " (maybe because of permissions)");
            return;
        }

        File[] files = dir.listFiles();
        path = buildPath(path, dir.getName());
        System.out.println("Adding Directory " + path);

        for (File source : files)
        {
            if (source.isDirectory())
            {
                zipDir(zos, path, source);
            } else
            {
                zipFile(zos, path, source);
            }
        }

        System.out.println("Leaving Directory " + path);
    }

    private static void zipFile(ZipOutputStream zos, String path, File file) throws IOException
    {
        if (!file.canRead())
        {
            System.out.println("Cannot read " + file.getCanonicalPath() + " (maybe because of permissions)");
            return;
        }

        System.out.println("Compressing " + file.getName());
        zos.putNextEntry(new ZipEntry(buildPath(path, file.getName())));

        FileInputStream fis = new FileInputStream(file);

        byte[] buffer = new byte[4092];
        int byteCount = 0;
        while ((byteCount = fis.read(buffer)) != -1)
        {
            zos.write(buffer, 0, byteCount);
            System.out.print('.');
            System.out.flush();
        }
        System.out.println();

        fis.close();
        zos.closeEntry();
    }
}

Enjoy!

EDIT: To check if the program is still busy, you can add the three lines I marked with a (*)

EDIT 2: Try the new code. On my platform, it runs correct (OS X). I'm not sure but, there might be some limited read permissions for files in Windows in AppData.

Aweless answered 11/4, 2012 at 10:14 Comment(7)
Thanks! I'll see how it goes! EDIT: It looked good, it DID compress it (:D), but it's apparently invalid. Error: The Compressed (zipped) Folder 'F:\David-PC\2012-03-11-25\2012-03-11-25.zip' is invalid.Hexahydrate
Wait - Hmm, weird. It automatically terminated itself for no reason. "Done." diddn't appear.Hexahydrate
@cheese5505: Make sure that you give the program the needed time. Compression takes some time. Make sure the application is terminated before you try to open the zip. You could add a System.out.print("."); in the compression loop, to see if the program is still busy or not.Aweless
Well, I did. I exported it and ran it through CMD, but it stops suddenly. Is there a time limit? Here's the last data it sends: Leaving Directory David/AppData/Local/Apple Computer/QuickTime Adding Directory David/AppData/Local/Apple Computer/WebKit Leaving Directory David/AppData/Local/Apple Computer/WebKit Leaving Directory David/AppData/Local/Apple Computer Adding Directory David/AppData/Local/Application Data C:\Users\David\Desktop>Hexahydrate
Still stopped, but it went alot further.Hexahydrate
You'd think if java was going to provide a zip api, there would be a method like the one you just wrote. Nice work.Tope
So you mean that to add an entry to an existing zip, you need to create a new file with the original zipped content, then add the new entry to it? Sounds inefficient but then I guess it's unavoidable since zip format is at the end of the file...Forlini
F
2

See also ZeroTurnaround's Zip library. It has such features as (citation):

  • pack and unpack directories recursively
  • iterate through ZIP entries
Floriated answered 11/4, 2012 at 10:22 Comment(1)
it wasn't broken 9 years ago ;)Floriated
F
1

I'll add another way using Java 7 NIO FileSystem. It uses the fact that JAR files are actually ZIP:

static public void addToZip(Path zip, Path file) throws IOException {
    Map<String,String> env = new HashMap<>();
    env.put("create", "false"); // We don't create the file but modify it
    
    URI uri = URI.create("jar:file:"+zip.toString());
    try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
        Path f = zipfs.getPath(file.getFileName().toString());
        Files.copy(file, f, StandardCopyOption.REPLACE_EXISTING);
    }
}
Forlini answered 28/6, 2021 at 13:20 Comment(2)
Your code does not compile!Greatest
@Greatest what exactly doesn't compile? It does compile on my computer...Forlini

© 2022 - 2024 — McMap. All rights reserved.