我的应用是通过SMTP服务器接收电子邮件.电子邮件和电子邮件附件中有一个或多个附件返回byte [](使用sun javamail api).
我试图动态压缩附件文件而不先将它们写入磁盘.
有什么/可能的方法来实现这一结果?
我正在下载包含XML的压缩文件,我想避免在操作它们之前将zip文件写入磁盘,因为延迟要求.但是,java.util.zip对我来说还不够.没有办法说"这是一个zip文件的字节数组,使用它"而不将其转换为流,并且ZipInputStream不可靠,因为它会扫描条目标题(请参阅下面的编辑,了解为什么不可靠).
我还没有访问我将要处理的zip文件,所以我不知道我是否能够通过它来处理它们ZipInputStream,我需要找到一个适用于任何有效ZIP文件的解决方案,作为一旦我投入生产失败的惩罚将会很高.
假设ZipInputStream不起作用,在没有条目头的情况下,我该怎么做才能解决这个问题?我正在使用维基百科的定义,其中包括如何正确解压缩zip文件(下面引用)作为标准.
编辑
Apache Commons Zip库对使用Stream(他们的解决方案和Java)的一些问题进行了很好的描述.我将进一步补充,从维基百科和个人经验来看,条目标题上的大小和crc字段可能无法填充(我在这些字段中的文件为-1).感谢centic提供此链接.
另外,让我引用维基百科的主题:
正确读取zip存档的工具必须扫描各个字段的签名,即zip中心目录.它们不能扫描条目,因为只有目录指定文件块的开始位置.扫描可能导致误报,因为格式不禁止其他数据在块之间或包含此类签名的未压缩流之间.
请注意,ZipInputStream扫描条目,而不是中心目录,这是它的问题.
最终编辑
如果有人感兴趣,可以使用此脚本生成无法ZipInputStream从现有ZIP文件中读取的有效ZIP文件.因此,作为对这个封闭问题的最终编辑,我需要一个可以读取文件的库,例如这个脚本生成的文件.
最近我在一个需要比以前更多的IO交互的项目上工作,我觉得我想要查看常规库(特别是Commons IO)并解决更深入的IO问题.
作为学术测试,我决定实现一个基本的,多线程的HTTP下载器.这个想法很简单:提供一个下载URL,代码将下载该文件.为了提高下载速度,文件被分块并且每个块同时下载(使用HTTP Range: bytes=x-x头)以使用尽可能多的带宽.
我有一个工作原型,但你可能已经猜到了,它并不完全理想.目前我手动启动3个"下载程序"线程,每个线程下载文件的1/3.这些线程使用通用的同步"文件编写器"实例来实际将文件写入磁盘.完成所有线程后,"文件编写器"完成,任何打开的流都关闭.一些代码片段可以给你一个想法:
线程启动:
ExecutorService downloadExecutor = Executors.newFixedThreadPool(3);
...
downloadExecutor.execute(new Downloader(fileWriter, download, start1, end1));
downloadExecutor.execute(new Downloader(fileWriter, download, start2, end2));
downloadExecutor.execute(new Downloader(fileWriter, download, start3, end3));
Run Code Online (Sandbox Code Playgroud)
每个"下载程序"线程下载一个块(缓冲)并使用"文件编写器"写入磁盘:
int bytesRead = 0;
byte[] buffer = new byte[1024*1024];
InputStream inStream = entity.getContent();
long seekOffset = chunkStart;
while ((bytesRead = inStream.read(buffer)) != -1)
{
fileWriter.write(buffer, bytesRead, seekOffset);
seekOffset += bytesRead;
}
Run Code Online (Sandbox Code Playgroud)
"文件写入器"使用RandomAccessFileto seek()和write()磁盘块写入磁盘:
public synchronized void write(byte[] bytes, int len, long start) throws IOException
{
output.seek(start); …Run Code Online (Sandbox Code Playgroud) 我需要从我的Web应用程序执行大量的文件下载.
显然,这是一个长期运行的行动(它将每年使用一次[-per-customer]),所以时间不是问题(除非它达到一些超时,但我可以通过创造某种形式的keepalive心跳).我知道如何创建一个隐藏的iframe并使用它content-disposition: attachment来尝试下载文件而不是在浏览器中打开它,以及如何实例化客户端 - 服务器通信以绘制进度表;
下载的实际大小(和文件数量)是未知的,但为了简单起见,我们实际上可以将其视为1GB,由100个文件组成,每个10MB.
由于这应该是一键操作,我的第一个想法是将所有文件分组,同时从动态生成的ZIP中从数据库中读取它们,然后要求用户保存ZIP.
问题是:在WebApp中从多个小字节数组创建大型存档时,最佳实践是什么,以及已知的缺点和陷阱是什么?
这可以随机分为:
当我创建zip存档时java.util.zip.*,有没有办法在多个卷中拆分生成的存档?
假设我的整个存档有一个filesize,24 MB我想将它分成3个文件,每个文件的限制为10 MB.
是否有具有此功能的zip API?或者其他任何好方法来实现这一目标?
谢谢索尔斯滕
我正在使用Java为我的应用程序创建一个备份例程.但是,当zip文件超过4GB或文件(大约)超过65,000时,zip文件已损坏.
我也在测试Apache Commons Compression压缩到tar.gz,但文件名限制为100个字符.我想测试这个压缩到压缩的API,但我想知道java zip的问题究竟是什么.
所以,真正的问题是:我做错了什么,它是Java Zip实现的限制,还是Zip格式本身的限制?
谢谢.
我正在尝试在JAVA中打开一个ZIP文件.
下面的代码工作正常,除了一些大文件,在这种情况下,我得到以下异常:
Exception in thread "main" java.util.zip.ZipException: invalid CEN header (bad signature)
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(ZipFile.java:114)
at java.util.zip.ZipFile.<init>(ZipFile.java:75)
Run Code Online (Sandbox Code Playgroud)
有没有已知的bug?是否可能是由于JAVA不支持更高的压缩级别?
请注意,我无法使用Winzip来解压缩文件,而Linux下的gzip会出现有关数据长度的错误(未压缩文件大约为80 GB).我不得不使用以下解决方法来解压缩它:
gunzip -S .zip < file.zip > file
Run Code Online (Sandbox Code Playgroud)
任何想法都会非常有帮助.
码:
if (file.getExtension().equals("gz")) {
br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(name))));
}
else if (file.getExtension().equals("zip")) {
ZipFile zipFile = new ZipFile(name); // <-------------------FAILS HERE
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry zipEntry = entries.nextElement();
System.out.println("ZIP File in the archive:" + zipEntry.getName());
br = new BufferedReader(new InputStreamReader(zipFile.getInputStream(zipEntry)));
break; …Run Code Online (Sandbox Code Playgroud) java ×8
zip ×7
backup ×1
exception ×1
filesystems ×1
gzip ×1
header ×1
http ×1
inputstream ×1
io ×1
large-files ×1
performance ×1
tar ×1