【问题标题】:Java - Calculate File CompressionJava - 计算文件压缩率
【发布时间】:2023-12-17 13:37:01
【问题描述】:

有没有办法在读取文件时获得可能的压缩率?
你知道,有些文件比其他文件更容易压缩...我的软件必须告诉我我的文件可能压缩的百分比。

例如
Compression Ratio: 50% -> 压缩文件可以节省 50% 的空间
Compression Ratio: 99% -> 压缩文件只能节省 1% 的空间

【问题讨论】:

  • 不碰它。包括阅读吗?我很确定没有办法做到这一点。
  • 您使用的是什么 API?请提供更多详细信息。
  • 你说的不碰它是什么意思?如果您的意思是不阅读整个文件,那么没有。如果我们被允许读取文件,那么显然。奇怪的问题!
  • 抱歉,可能不清楚...我的意思是“只是阅读它”:) 我不知道哪些 API 可用,这是一个“理论”问题
  • 您可以做的最好的事情是压缩一些文件(如果它很大)并将其用作估计值。如果它很小,除非您压缩整个文件,否则估计会很差。

标签: java file compression zip rar


【解决方案1】:

首先,这在很大程度上取决于您选择的压缩方法。其次,我严重怀疑如果不计算与实际进行压缩相当的时间和空间复杂度,这是可能的。我想说你最好的办法是压缩文件,跟踪你已经生成的文件的大小并删除/释放它(一旦你完成它,显然)而不是写出来。

要真正做到这一点,除非你真的想自己实现它,否则使用java.util.zip 类可能是最简单的,尤其是Deflater 类及其deflate 方法。

【讨论】:

  • 好吧,我从未研究过文件压缩参数,我对方法的想法很少……我想我会使用 .zip 或 .rar 等经典存档格式
  • 关于时间复杂度,我知道它与压缩本身成正比,但肯定更快!我不想要压缩工具,我只想分析我的文件
  • @Oneiros 至少,您需要查看文件的每个字节并跟踪每个字节有多少。您也许可以停下来,找到熵,然后用它来计算理论上的最佳压缩。但我怀疑这会明显更快。
  • 谢谢你,你的解释很有用 :) 好吧,我想我应该找到一个很好的速度-精度折衷方案
【解决方案2】:

首先,您需要研究信息论。信息论领域有两种理论:

  1. 根据 Shannon 的说法,可以通过使用源的符号概率来计算源的熵(即压缩大小)。因此,由在每一步产生符号概率的统计模型定义的最小压缩大小。所有算法都隐式或显式地使用该方法来压缩数据。查看Wikipedia article 了解更多详情。
  2. 根据 Kolmogorov 的说法,可以通过找到生成源的最小可能程序来找到最小的压缩大小。从这个意义上说,它不可能是可计算的。一些程序部分地使用这种方法来压缩数据(例如,您可以编写一个小型控制台应用程序,它可以生成 100 万位 PI,而不是压缩那 100 万位 PI)。

因此,如果不评估实际压缩,就无法找到压缩大小。但是,如果您需要一个近似值,您可以依靠香农的熵理论并建立一个简单的统计模型。这是一个非常简单的解决方案:

  1. 计算源文件中每个符号的 1 阶统计数据。
  2. 使用这些统计数据计算熵。

您的估计将或多或少与 ZIP 的默认压缩算法(放气)相同。 Here 是同一想法的更高级版本(请注意它使用大量内存!)。它实际上使用熵来确定块边界,以应用分割将文件划分为同质数据。

【讨论】:

    【解决方案3】:

    不检查文件是不可能的。您唯一能做的就是根据通过实际压缩和测量从相对较大的样本中收集的统计数据,按文件扩展名获得近似比率。例如,统计分析可能会显示 .zip、.jpg 不可高度压缩,但 .txt 和 .doc 等文件可能可高度压缩。

    此结果仅供粗略指导,在某些情况下可能会有所偏差,因为绝对不能保证文件扩展名的可压缩性。该文件可以包含任何内容,无论扩展名说明它可能是或不是。

    更新:假设您可以检查文件,那么您可以使用 java.util.zip API 读取原始文件并对其进行压缩,然后查看之前/之后的区别。

    【讨论】:

    • 对不起,我的问题不清楚:我当然可以检查文件
    • 我对更新的回答:它对我没有帮助,因为我只想分析我的文件......想象一下这种情况:我有一个包含很多大文件的文件夹(任何类型)在我的驱动器上。我需要一个工具来帮助我优化驱动器的空间,告诉我“好的,这些文件可以有很好的压缩,压缩它们”,但我不想等待整个压缩所需的时间,我不想不需要压缩过程!如果它压缩所有文件然后给我分析它,那将是一个愚蠢的工具......
    • 那就参考我原来的答案。或者,如果文件非常大,请先压缩其中的 1MB,以获得压缩的粗略近似值。