繁体   English   中英

使用DotNetZip将文件从Base64解压缩到字符串

[英]Unzipping a file from Base64 to string using DotNetZip

当我尝试在代码中解压缩文件时,我收到以下错误。

   at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen)
   at System.IO.StreamReader..ctor(Stream stream)
   at Arkle.AzureServiceBusSample.MessageFetcher.ConvertBase64ZippedStringToNormalString(String stringBase64Zipped) in c:\CodeTfsArklePosBenLenovo\Arkle.AzureServiceBusSample\Arkle.AzureServiceBusSample\MessageFetcher.cs:line 171
   at Arkle.AzureServiceBusSample.MessageFetcher.DownloadMessages(String username, String password, String identifier) in c:\CodeTfsArklePosBenLenovo\Arkle.AzureServiceBusSample\Arkle.AzureServiceBusSample\MessageFetcher.cs:line 92
   at Arkle.AzureServiceBusSample.MessageFetcher.ReceiveMessages(String username, String password, String endPoint, String subscriptionName) in c:\CodeTfsArklePosBenLenovo\Arkle.AzureServiceBusSample\Arkle.AzureServiceBusSample\MessageFetcher.cs:line 48

System.ArgumentException:Stream无法读取。 System.IO.StreamReader..ctor(Stream stream)中的System.IO.StreamReader..ctor(Stream stream,Encoding encoding,Boolean detectEncodingFromByteOrderMarks,| nt32 bufferSize,Boolean | eaveOpen)

它发生在行var streamReader1 = new StreamReader(ms); 我已经检查过,只是在上面我能够将文件保存到磁盘并且正确解压缩。 但是我需要将其直接解压缩到内存流中。

我正在使用DotNetZip版本1.9.2。

我的代码:

    using ionic.zip;

    .............
    public static string UnzipToString(string stringBase64Zipped)
    {
        var bytesZipFile = Convert.FromBase64String(stringBase64Zipped);

        var msZipFile = new MemoryStream(bytesZipFile);
        msZipFile.Position = 0;
        using (var zipFile1 = ZipFile.Read(msZipFile))
        {
            zipFile1.Save(string.Format(@"C:\Temp\{0}.zip", Guid.NewGuid()));  // This works
            var zipEntry1 = zipFile1.Entries.First();

            using (var ms = new MemoryStream())
            {
                ms.Position = 0;
                zipEntry1.Extract(ms);
                var streamReader1 = new StreamReader(ms);
                var result = String.Empty;
                ms.Position = 0;
                result = streamReader1.ReadToEnd();

                return result;
            }
        }
    }

停止时的行和错误

当我尝试根据下面的建议将memeorystream位置设置为0时,我现在遇到了一个新错误。

System.ObjectDisposedException: Cannot access a closed Stream.

   at System.IO.__Error.StreamIsClosed()

   at System.IO.MemoryStream.set_Position(Int64 value)

   at Arkle.AzureServiceBusSample.MessageFetcher.ConvertBase64ZippedStringToNormalString(String stringBase64Zipped) in c:\CodeTfsArklePosBenLenovo\Arkle.AzureServiceBusSample\Arkle.AzureServiceBusSample\MessageFetcher.cs:line 171

   at Arkle.AzureServiceBusSample.MessageFetcher.DownloadMessages(String username, String password, String identifier) in c:\CodeTfsArklePosBenLenovo\Arkle.AzureServiceBusSample\Arkle.AzureServiceBusSample\MessageFetcher.cs:line 92

   at Arkle.AzureServiceBusSample.MessageFetcher.ReceiveMessages(String username, String password, String endPoint, String subscriptionName) in c:\CodeTfsArklePosBenLenovo\Arkle.AzureServiceBusSample\Arkle.AzureServiceBusSample\MessageFetcher.cs:line 48
zipEntry1.Extract(ms);
ms.Position = 0;
var streamReader1 = new StreamReader(ms);

将MemoryStream位置重置为流的开头。

不确定你将成为什么样的人。 这是我的示例代码

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            var bytes = File.ReadAllBytes(@"e:\scripts_04-10-2014.zip");
            var zipAsBase64 = Convert.ToBase64String(bytes);

            foreach (var item in GetUnzippedItemsAsStream(zipAsBase64))
            {
                using (var fs = new FileStream(Path.Combine(@"e:\", item.Item1), FileMode.CreateNew,
                        FileAccess.ReadWrite))
                {
                    item.Item2.CopyTo(fs);
                }
            }
        }

        public IEnumerable<Tuple<string, Stream>> GetUnzippedItemsAsStream(string stringBase64Zipped)
        {
            var bytesZipFile = Convert.FromBase64String(stringBase64Zipped);
            using (var ms = new MemoryStream(bytesZipFile))
            {
                using (var zipFile = ZipFile.Read(ms))
                {
                    foreach (var zipEntry in zipFile.Entries)
                    {
                        var outputStream = new MemoryStream();
                            zipEntry.Extract(outputStream);
                            yield return new Tuple<string, Stream>(zipEntry.FileName, new MemoryStream(outputStream.ToArray()));
                    }
                }
            }
        }

请注意以下代码

  zipEntry.Extract(outputStream);
  yield return new Tuple<string, Stream>(zipEntry.FileName, new MemoryStream(outputStream.ToArray()));

我需要使用old.ToArray()创建新的MemoryStream( 它甚至可以用于关闭的MemoryStream ),因为当前的DotNetZipLib中存在一个关于提取后关闭流的已知问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM