Java 7zip压缩太大了

Mad*_*ist 7 java compression zip 7zip

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

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Apache Commons Compress库

编辑:这是一个链接,我有一些Apache Commons Compress代码.

df7*_*899 6

Commons Compress在每个归档条目的容器文件中启动一个新块.请注意块计数器:

块每个文件

不是你希望得到的答案,但文档说它不支持"固体压缩" - 将几个文件写入一个块.请参阅此处文档中的第5段.

快速浏览一下其他几个支持LZMA压缩的Java库,但我找不到一个可以在7-Zip的父容器文件格式中这样做的库.也许其他人知道另一种选择......

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


Mat*_*ieu 5

我没有足够的代表发表评论,所以这是我的想法:

  • 我没有看到你设置压缩率的位置,因此它可能不SevenZOutputFile使用(或非常低)压缩.正如@CristiFati所说,压缩的差异是奇怪的,特别是对于文本文件
  • 如@ df778899所述,不支持实体压缩,这是实现最佳压缩比的方式,因此您将无法像7z命令行那样做

也就是说,如果zip真的不是一个选项,你的最后一可能是直接在你的程序中调用正确的命令行.

如果纯7z不是强制性的,另一种选择是使用类似"tgz"的格式来模拟实体压缩:首先将所有文件压缩为非压缩文件(例如tar格式或没有压缩的zip文件),然后压缩zip模式下的单个文件,带有标准的Java Deflate算法.当然,只有当该格式被使用它的进一步过程识别时,这才是可行的.


Tiy*_*ebM 5

使用7-Zip文件存档,它832 KB可以26.0 KB轻松压缩 文件:

  1. 获取它的JarSDK.
  2. 选择LZMA Compression .java相关文件.
  3. Run向项目属性添加参数:e "D:\\2017ASP.pdf" "D:\\2017ASP.7z",e代表encode,"input path" "output path".
  4. 运行项目[LzmaAlone.java].

结果

Case1(.pdf文件):从.33,969 KB24,645 KB.

Case2(.docx文件):从.832 KB26.0 KB.