以编程方式创建 ZIP 文件
我的应用程序将把大量缓存数据存储到本地存储,以提高性能和断开连接。我尝试使用 SharpZipLib 来压缩创建的缓存文件,但遇到了一些困难。
我可以创建文件,但它是无效的。 Windows的内置zip系统和7-zip都表明该文件无效。当我尝试通过 SharpZipLib 以编程方式打开文件时,出现“错误的中央目录签名”异常。我认为部分问题是我直接从 MemoryStream 创建 zip 文件,因此没有“根”目录。不确定如何使用 SharpZipLib 以编程方式创建一个。
下面的 EntityManager 是 IdeaBlade DevForce 生成的“数据上下文”。它可以将其内容保存到流中,以便序列化到磁盘进行缓存。
这是我的代码:
private void SaveCacheFile(string FileName, EntityManager em)
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(FileName, System.IO.FileMode.CreateNew, isf))
{
MemoryStream inStream = new MemoryStream();
MemoryStream outStream = new MemoryStream();
Crc32 crc = new Crc32();
em.CacheStateManager.SaveCacheState(inStream, false, true);
inStream.Position = 0;
ZipOutputStream zipStream = new ZipOutputStream(outStream);
zipStream.IsStreamOwner = false;
zipStream.SetLevel(3);
ZipEntry newEntry = new ZipEntry(FileName);
byte[] buffer = new byte[inStream.Length];
inStream.Read(buffer, 0, buffer.Length);
newEntry.DateTime = DateTime.Now;
newEntry.Size = inStream.Length;
crc.Reset();
crc.Update(buffer);
newEntry.Crc = crc.Value;
zipStream.PutNextEntry(newEntry);
buffer = null;
outStream.Position = 0;
inStream.Position = 0;
StreamUtils.Copy(inStream, zipStream, new byte[4096]);
zipStream.CloseEntry();
zipStream.Finish();
zipStream.Close();
outStream.Position = 0;
StreamUtils.Copy(outStream, isfs, new byte[4096]);
outStream.Close();
}
}
}
My application will be storing large amounts of cached data to local storage for performance and disconnected purposes. I have tried to use SharpZipLib to compress the cache files that are created, but I'm having some difficulty.
I can get the file created, but it is invalid. Windows' built-in zip system and 7-zip both indicate that the file is invalid. When I attempt to open the file programmatically through SharpZipLib, I get the exception "Wrong Central Directory signature." I think part of the problem is that I'm creating the zip file directly from a MemoryStream, so there is no "root" directory. Not sure how to create one programmatically with SharpZipLib.
The EntityManager below is the IdeaBlade DevForce-generated "datacontext." It can save its contents to a stream for purposes of serializing to disk for caching.
Here's my code:
private void SaveCacheFile(string FileName, EntityManager em)
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(FileName, System.IO.FileMode.CreateNew, isf))
{
MemoryStream inStream = new MemoryStream();
MemoryStream outStream = new MemoryStream();
Crc32 crc = new Crc32();
em.CacheStateManager.SaveCacheState(inStream, false, true);
inStream.Position = 0;
ZipOutputStream zipStream = new ZipOutputStream(outStream);
zipStream.IsStreamOwner = false;
zipStream.SetLevel(3);
ZipEntry newEntry = new ZipEntry(FileName);
byte[] buffer = new byte[inStream.Length];
inStream.Read(buffer, 0, buffer.Length);
newEntry.DateTime = DateTime.Now;
newEntry.Size = inStream.Length;
crc.Reset();
crc.Update(buffer);
newEntry.Crc = crc.Value;
zipStream.PutNextEntry(newEntry);
buffer = null;
outStream.Position = 0;
inStream.Position = 0;
StreamUtils.Copy(inStream, zipStream, new byte[4096]);
zipStream.CloseEntry();
zipStream.Finish();
zipStream.Close();
outStream.Position = 0;
StreamUtils.Copy(outStream, isfs, new byte[4096]);
outStream.Close();
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
直接从内存创建 zip 文件不是您的问题。 SharpZipLib 使用 ZipEntry 构造函数中的参数来确定路径,并且不关心该路径是否有子目录。
Creating a zip file straight from memory is not your problem. SharpZipLib uses the parameter in the
ZipEntry
constructor to determine the path, and does not care if that path has subdirectories or not.删除
outStream.Position = 0;
就可以了。Remove
outStream.Position = 0;
and it works.