Java 7zip 压缩太大

标签 java zip compression 7zip

我有一个 Java 程序,它搜索包含昨天日期的文件夹并将其压缩为 7zip 文件并在最后删除它。现在我注意到我的程序生成的 7zip 存档文件太大了。当我使用像 7-Zip 文件管理器这样的程序来压缩我的文件时,它会生成一个 5 kb 大的存档,而我的程序会为相同的文件(具有 873 kb 大小)生成一个 737 kb 大的存档。现在恐怕我的程序不会将其压缩为 7zip 文件,而是压缩为普通的 zip 文件。有没有办法更改我的代码中的某些内容,以便它生成一个较小的 7zip 文件,就像 7-Zip 文件管理器那样?

package SevenZip;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;

public class SevenZipUtils {

    public static void main(String[] args) throws InterruptedException, IOException {

        String sourceFolder = "C:/Users/Ferid/Documents/Dates/";
        String outputZipFile = "/Users/Ferid/Documents/Dates";
        int sleepTime = 0;
        compress(sleepTime, outputZipFile, sourceFolder);
    }

    public static boolean deleteDirectory(File directory, int sleepTime) throws InterruptedException {
        if (directory.exists()) {
            File[] files = directory.listFiles();
            if (null != files) {
                for (int i = 0; i < files.length; i++) {
                    if (files[i].isDirectory()) {
                        deleteDirectory(files[i], sleepTime);
                        System.out.println("Folder deleted: " + files[i]);
                    } else {
                        files[i].delete();
                        System.out.println("File deleted: " + files[i]);
                    }
                }
            }
        }
        TimeUnit.SECONDS.sleep(sleepTime);
        return (directory.delete());
    }

    public static void compress(int sleepTime, String outputZipFile, String sourceFolder)
            throws IOException, InterruptedException {

        // finds folder of yesterdays date
        final Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1); // date of yesterday
        String timeStamp = new SimpleDateFormat("yyyyMMdd").format(cal.getTime()); // format the date
        System.out.println("Yesterday was " + timeStamp);

        if (sourceFolder.endsWith("/")) { // add yesterday folder to sourcefolder path
            sourceFolder = sourceFolder + timeStamp;
        } else {
            sourceFolder = sourceFolder + "/" + timeStamp;
        }

        if (outputZipFile.endsWith("/")) { // add yesterday folder name to outputZipFile path
            outputZipFile = outputZipFile + " " + timeStamp + ".7z";
        } else {
            outputZipFile = outputZipFile + "/" + timeStamp + ".7z";
        }

        File file = new File(sourceFolder);

        if (file.exists()) {
            try (SevenZOutputFile out = new SevenZOutputFile(new File(outputZipFile))) {
                addToArchiveCompression(out, file, ".");
                System.out.println("Files sucessfully compressed");

                deleteDirectory(new File(sourceFolder), sleepTime);
            }
        } else {
            System.out.println("Folder does not exist");
        }
    }

    private static void addToArchiveCompression(SevenZOutputFile out, File file, String dir) throws IOException {
        String name = dir + File.separator + file.getName();
        if (file.isFile()) {
            SevenZArchiveEntry entry = out.createArchiveEntry(file, name);
            out.putArchiveEntry(entry);

            FileInputStream in = new FileInputStream(file);
            byte[] b = new byte[1024];
            int count = 0;
            while ((count = in.read(b)) > 0) {
                out.write(b, 0, count);
            }
            out.closeArchiveEntry();
            in.close();
            System.out.println("File added: " + file.getName());
        } else if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (children != null) {
                for (File child : children) {
                    addToArchiveCompression(out, child, name);
                }
            }
            System.out.println("Directory added: " + file.getName());
        } else {
            System.out.println(file.getName() + " is not supported");
        }
    }
}

我正在使用 Apache Commons Compress library

编辑:这是一个 link我从中获得了一些 Apache Commons Compress 代码。

最佳答案

Commons Compress 正在为每个存档条目在容器文件中启动一个新 block 。注意这里的 block 计数器:

block-per-file

不是您所希望的答案,但文档说它不支持“固体压缩”——将多个文件写入一个 block 。请参阅文档中的第 5 段 here .

快速浏览了一下,发现了其他一些支持 LZMA 压缩的 Java 库,但我无法在 7-Zip 的父容器文件格式中找到可以这样做的库。也许其他人知道替代方案...

这听起来像是普通的 zip 文件格式(例如通过 ZipOutputStream )不是一个选项?

关于Java 7zip 压缩太大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54075881/

相关文章:

java - 检测 Java 中的 Dll

java - 在 Websphere Application Server 上运行基于 Filenet 的 Web 应用程序时出现凭据异常

javascript - 将多个文件放入 zip 文件中并使用 javascript 下载

java - 如何在 Jetty 8 中添加请求日志过滤器?

PHP 从 2 个字符串变量生成一个 zip 文件

php - 任何人都知道 PHP 系统命令行 zip 的一个很好的例子

compression - 如何快速检查 zip 文件是否损坏?

java - 通过 GZIP 流读写对象?

php - 压缩存储在mysql中的数据

Java ConcurrentHashMap 原子获取和放置