[英]How to estimate zip file size in java before creating it
我有一个要求,我必须从可用文件列表中创建一个zip文件。 这些文件有不同的类型,如txt,pdf,xml等。我正在使用java util类来完成它。
这里的要求是保持最大文件大小为5 MB。 我应该根据时间戳从列表中选择文件,将文件添加到zip,直到zip文件大小达到5 mb。 我应该跳过剩下的文件。
请告诉我,如果在java中有一种方法,我可以提前估计zip文件大小而不创建实际文件?
或者有没有其他方法来处理这个问题
将ZipOutputStream包装到个性化的OutputStream中,命名为YourOutputStream。
ZipOutputStream
(zos2),它包装一个新的ByteArrayOutputStream
(baos) public YourOutputStream(ZipOutputStream zos, int maxSizeInBytes)
YourOutputStream
编写文件时,它将首先在zos2上编写它 public void writeFile(File file) throws ZipFileFullException
public void writeFile(String path) throws ZipFileFullException
baos.size()
在maxSizeInBytes
您需要两个ZipOutputStream,一个要写在您的驱动器上,一个用于检查您的内容是否超过5MB。
编辑:事实上我检查过, 你不能轻易删除ZipEntry 。
http://download.oracle.com/javase/6/docs/api/java/io/ByteArrayOutputStream.html#size()
Colin Herbert的+1:逐个添加文件,要么备份上一步,要么删除最后一个文件(如果存档很大)。 我只是想补充一些细节:
预测太不可靠了。 例如,PDF可以包含未压缩的文本,并压缩到原始文本的30%,或者它包含已经压缩的文本和图像,压缩到80%。 您需要检查整个PDF的可压缩性,基本上必须压缩它们。
您可以尝试统计预测 ,但这可以减少尝试失败的次数,但您仍然需要实施上述建议。 首先使用更简单的实现,看看它是否足够。
或者,单独压缩文件 ,然后选择绑定在一起不超过5 MB的文件。 如果解压缩也是自动化的,您可以将zip文件绑定到单个未压缩的zip文件中。
也许你每次都可以添加一个文件,直到达到5MB的限制,然后丢弃最后一个文件。 像@Gopi一样,我认为没有任何方法可以在不实际压缩文件的情况下估算它。
当然,文件大小不会增加(或者可能是一点,因为zip标题?),所以至少你有一个“最坏情况”估计。
只想分享我们如何实施手动方式
int maxSizeForAllFiles = 70000; // Read from property
int sizePerFile = 22000; // Red from property
/**
* Iterate all attachment list to verify if ZIP is required
*/
for (String attachFile : inputAttachmentList) {
File file = new File(attachFile);
totalFileSize += file.length();
/**
* if ZIP required ??? based on the size
*/
if (file.length() >= sizePerFile) {
toBeZipped = true;
logger.info("File: "
+ attachFile
+ " Size: "
+ file.length()
+ " File required to be zipped, MAX allowed per file: "
+ sizePerFile);
break;
}
}
/**
* Check if all attachments put together cross MAX_SIZE_FOR_ALL_FILES
*/
if (totalFileSize >= maxSizeForAllFiles) {
toBeZipped = true;
}
if (toBeZipped) {
// Zip Here iterating all attachments
}
我不认为有任何方法可以估计将创建的zip的大小,因为拉链被处理为流。 除非您实际压缩它,否则在技术上不可能预测创建的压缩格式的大小。
我在具有已知输入类型的项目上执行了一次。 我们知道一般来说我们的数据压缩在5:1左右(这是所有文本。)所以,我检查文件大小并除以5 ...
在这种情况下,这样做的目的是检查文件是否可能低于特定大小。 我们只需粗略估计。
总而言之,我注意到像7zip这样的zip应用程序会创建一个特定大小的zip文件(如CD),然后一旦达到限制就将zip拆分为新文件。 您可以查看该源代码。 我之前在代码中实际使用过该应用程序的命令行版本。 他们有一个你也可以使用的图书馆。 不知道与Java集成的程度如何。
为了它的价值,我还使用了一个名为SharpZipLib的库。 非常好。 我想知道是否有Java端口。
有一个更好的选择。 创建一个只计算写入字节的虚拟LengthOutputStream
:
public class LengthOutputStream extends OutputStream {
private long length = 0L;
@Override
public void write(int b) throws IOException {
length++;
}
public long getLength() {
return length;
}
}
您只需将LengthOutputStream
连接到ZipOutputStream
:
public static long sizeOfZippedDirectory(File dir) throws FileNotFoundException, IOException {
try (LengthOutputStream sos = new LengthOutputStream();
ZipOutputStream zos = new ZipOutputStream(sos);) {
... // Add ZIP entries to the stream
return sos.getLength();
}
}
LengthOutputStream
对象计算压缩流的字节数但不存储任何内容,因此没有文件大小限制。 此方法提供准确的大小估计,但几乎与创建ZIP文件一样慢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.