Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ZipArchive创建了无效的ZIP文件_C#_.net_Windows 8_Ziparchive - Fatal编程技术网

C# ZipArchive创建了无效的ZIP文件

C# ZipArchive创建了无效的ZIP文件,c#,.net,windows-8,ziparchive,C#,.net,Windows 8,Ziparchive,我正在尝试用一个条目从代码创建一个新的ZIP包,并将该ZIP包保存到一个文件中。我正试图通过System.IO.Compression.ZipArchive类来实现这一点。我正在使用以下代码创建ZIP包: using (MemoryStream zipStream = new MemoryStream()) { using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create)) { v

我正在尝试用一个条目从代码创建一个新的ZIP包,并将该ZIP包保存到一个文件中。我正试图通过System.IO.Compression.ZipArchive类来实现这一点。我正在使用以下代码创建ZIP包:

using (MemoryStream zipStream = new MemoryStream())
{
    using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create))
    {
        var entry = zip.CreateEntry("test.txt");
        using (StreamWriter sw = new StreamWriter(entry.Open()))
        {
            sw.WriteLine(
                "Etiam eros nunc, hendrerit nec malesuada vitae, pretium at ligula.");
        }
然后我将ZIP保存到WinRT中的一个文件中:

        var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("test.zip", CreationCollisionOption.ReplaceExisting);
        zipStream.Position = 0;
        using (Stream s = await file.OpenStreamForWriteAsync())
        {
            zipStream.CopyTo(s);
        }
或在普通.NET 4.5中:

        using (FileStream fs = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
        {
            zipStream.Position = 0;
            zipStream.CopyTo(fs);
        }
但是,我无法在Windows资源管理器、WinRAR等中打开生成的文件(我检查了生成的文件的大小是否与zipStream的长度匹配,因此流本身已正确保存到文件中。)

我是做错了什么还是ZipArchive类有问题?

在所有流对象上,必须从beggining倒回流,以便其他应用程序使用.Seek方法正确读取流

例如:

zipStream.Seek(0, SeekOrigin.Begin);

事后看来,我在代码中发现了明显的错误。ZipArchive必须处理,以使其将内容写入其底层流。因此,我必须在ZipArchive的using块结束后将流保存到一个文件中。
将其构造函数的leaveOpen参数设置为true,使其不关闭底层流,这一点很重要。下面是完整的工作解决方案:

using (MemoryStream zipStream = new MemoryStream())
{
    using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
    {
        var entry = zip.CreateEntry("test.txt");
        using (StreamWriter sw = new StreamWriter(entry.Open()))
        {
            sw.WriteLine(
                "Etiam eros nunc, hendrerit nec malesuada vitae, pretium at ligula.");
        }
    }

    var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(
        "test.zip",
        CreationCollisionOption.ReplaceExisting);

    zipStream.Position = 0;
    using (Stream s = await file.OpenStreamForWriteAsync())
    {
        zipStream.CopyTo(s);
    }
}

您可以遵循相同的想法,只需使用类似文件流的源代码,以相反的顺序。我填写了以下表格,文件正常打开:

string fileFormat = ".zip"; // any format
string filename = "teste" + fileformat;

StorageFile zipFile = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(filename,CreationCollisionOption.ReplaceExisting);

using (Stream zipStream = await zipFile.OpenStreamForWriteAsync()){

   using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create)){
        //Include your content here
   }
}

完整的代码如下所示:

var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("test.zip",CreationCollisionOption.ReplaceExisting);
using (Stream zipStream = await zipFile.OpenStreamForWriteAsync())
{
    using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
    {
        var entry = zip.CreateEntry("test.txt");
        using (StreamWriter sw = new StreamWriter(entry.Open()))
        {
            sw.WriteLine("Etiam eros nunc, hendrerit nec malesuada vitae, pretium at ligula.");
        }
    }   
}
结果,您将获得归档文件“archive.zip”和单个条目文件“test.txt”。
您需要使用来避免与已处理的资源进行任何交互。

在我的情况下,问题是当zip文件任务完成时,我没有处理“zipArchive”
。即使我冲走并关闭了所有的溪流

因此,按照上述答案中的建议,使用或使用

using (var zipArchive = new ZipArchive(File.OpenWrite("archive.zip"), 
ZipArchiveMode.Create))
或者在任务结束时处理变量

zipArchive.Dispose();

这没有帮助。这就是为什么我将Position属性设置为0,我想这也会达到同样的效果。zip库必须有自己的SaveAs方法,试着研究一下,而且在项目高峰期,有各种不同保存方案的文档。嗯,ZipArchive类()没有SaveAs方法。你说的“项目页面”是什么意思?对不起,我以为它是第三方库。@Freeman我的情况就是这样。谢谢我得到一个错误,“名称“Windows”在当前上下文中不存在”。我该怎么纠正?Michael,这是一个构建错误,对吗?您是在开发Windows应用商店应用程序还是普通的.NET应用程序?在普通的.NET应用程序中,您应该使用
FileStream
类,而不是
Windows.storage
命名空间中的存储类。您可以在问题中看到一个示例。请为您的代码添加一个解释,以及它是如何解决问题的。@DouglasGaskell done。上面的代码可能没有直接回答问题,但展示了如何使用ZiparChiveZip压缩某些文件如果您添加的是二进制数据而不是字符串,这里有一个很好的示例:
zipArchive.Dispose();