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

时间:2014-04-11 09:34:49

标签: c# streamreader memorystream

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

   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,Encoding encoding,Boolean detectEncodingFromByteOrderMarks,| nt32 bufferSize,Boolean | eaveOpen) 在System.IO.StreamReader..ctor(Stream stream)

它发生在我已经检查过的行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;
            }
        }
    }

Line and error when it stopz

当我尝试根据下面的建议将记忆流位置设置为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

2 个答案:

答案 0 :(得分:1)

zipEntry1.Extract(ms);
ms.Position = 0;
var streamReader1 = new StreamReader(ms);

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

答案 1 :(得分:1)

不确定你将会成就什么。这是我的示例代码

        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()(which works even with closed MemoryStreams)创建新的MemoryStream,因为当前的DotNetZipLib中有known issue关于在解压缩后关闭流。