在PCL中,我使用SharpZipLib.Portable将一些内容压缩到MemoryStream中,然后使用PCLStorage的二进制写入工具将MemoryStream写入Zip文件。但是,我创建的zip文件已损坏。在列出其内容时,我收到消息:
存档:zippedfile.zip
warning [zippedfile.zip]:开头或zip文件中的20个额外字节
(无论如何都试图处理)
错误[zippedfile.zip]:找不到中心目录的开头;
zipfile损坏。
(请检查您是否已转移或创建了zip文件
适当的BINARY模式,你已经正确编译了UnZip)
代码如下。谁能建议我哪里出错?我暂时没有想到SharpZipLib或PCLStorage有什么问题,但是有一个奇怪的异常现象:
[编辑:下面描述的异常的一些新亮点:每次出现一个大于7F的字节被转换为三倍字节EF BF BD,这似乎是一个问号字符味道的UTF8多字节表示。所以看起来PCLStorage将流视为UTF8。那么问题似乎是,如何说服PCLStorage进行二进制转移。 ]
在将流传递给PCLStorage时,我在断点处检查流('verify'变量),并看到十六进制内容似乎与ZIP格式相似,例如具有正确的ZIP标头:
50 4B 03 04 14 00 00 00 08 00 45 89 52 48 DF 36 ......(122字节)
当我在十六进制编辑器中查看创建的zip文件时,我也看到了类似于ZIP格式的东西,但它在文件正文中是不同的! :
50 4B 03 04 14 00 00 00 08 00 45 EF BF BD 52 48 ...(142字节)
在这两种情况下,ASCII等效形式都是:
PK ....... ABCD.txt .... PK ..... ..... ABCD.txt PK .....
使用带有fileHandler.WriteAsync的代码而不是.CopyTo时的类似结果。
其他人使用PCLStorage二进制传输,所以我怀疑问题是否存在。我错过了什么?欢迎任何建议。
这是在Xamarin Forms PCL中。
// using ICSharpCode.SharpZipLib.Zip; // SharpZipLib.Portable
// using PCLStorage;
string content = "ABCD\r\n"; // Desired content of zipped file
byte[] contentBytes = Encoding.UTF8.GetBytes ( content );
using ( MemoryStream contentStream = new MemoryStream () )
{
await contentStream.WriteAsync ( contentBytes, 0, contentBytes.Length );
contentStream.Position = 0;
using ( MemoryStream zipStream = new MemoryStream () )
{
using ( ZipOutputStream s = new ZipOutputStream ( zipStream ) )
{
s.UseZip64 = UseZip64.Off;
s.SetLevel (6); // Compression level
//Add the text file
ZipEntry csvEntry = new ZipEntry ( "ABCD.txt" );
s.PutNextEntry ( csvEntry );
await contentStream.CopyToAsync (s);
s.CloseEntry ();
s.IsStreamOwner = false; // Do not close zipStream when finishing
await s.FlushAsync (); // Write to zipStream
s.Finish ();
}
// Save file to local file system
IFolder rootfolder = FileSystem.Current.LocalStorage;
IFolder exportfolder = await rootfolder.CreateFolderAsync ( "Exports", CreationCollisionOption.OpenIfExists );
IFolder subfolder = await exportfolder.CreateFolderAsync ( "Zips", CreationCollisionOption.OpenIfExists );
IFile file = await subfolder.CreateFileAsync ( "ZippedFile.zip", CreationCollisionOption.ReplaceExisting );
using (Stream fileHandler = await file.OpenAsync ( FileAccess.ReadAndWrite ) )
{
zipStream.Position = 0;
await zipStream.CopyToAsync ( fileHandler );
// As a sanity check, view the contents of fileHandler
using ( MemoryStream memStream = new MemoryStream () )
{
fileHandler.Position = 0;
fileHandler.CopyTo ( memStream );
byte[] verify = memStream.ToArray ();
} // Put breakpoint here to view contents of verify
}
}
答案 0 :(得分:0)
很抱歉,伙计们。我的错!写入的代码正确运行并在文件系统中生成有效的ZIP文件。我的测试工具代码就是问题。
- 比尔。