简体   繁体   English

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

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

When I am trying to unzip a file in code I get the following error. 当我尝试在代码中解压缩文件时,我收到以下错误。

   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 was not readable. System.ArgumentException:Stream无法读取。 at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, |nt32 bufferSize, Boolean |eaveOpen) at System.IO.StreamReader..ctor(Stream stream) System.IO.StreamReader..ctor(Stream stream)中的System.IO.StreamReader..ctor(Stream stream,Encoding encoding,Boolean detectEncodingFromByteOrderMarks,| nt32 bufferSize,Boolean | eaveOpen)

It happens on the line var streamReader1 = new StreamReader(ms); 它发生在行var streamReader1 = new StreamReader(ms); I have checked and just above that I am able to save the file to disk and it is unzipped correctly. 我已经检查过,只是在上面我能够将文件保存到磁盘并且正确解压缩。 However I need to unzip it directly to a memory stream. 但是我需要将其直接解压缩到内存流中。

I'm using DotNetZip version 1.9.2. 我正在使用DotNetZip版本1.9.2。

My Code: 我的代码:

    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;
            }
        }
    }

停止时的行和错误

I have got a new error now when I try and set the memeorystream position to 0 as per the suggestion below. 当我尝试根据下面的建议将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);

Reset the MemoryStream position to be the start of the stream. 将MemoryStream位置重置为流的开头。

Not sure what you are going to archieve. 不确定你将成为什么样的人。 Here is my sample code which works 这是我的示例代码

        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()));
                    }
                }
            }
        }

Please note the following code 请注意以下代码

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

I was needed to create new MemoryStream with old.ToArray() ( which works even with closed MemoryStreams ) because there is a known issue in current DotNetZipLib about closing the stream after extracting. 我需要使用old.ToArray()创建新的MemoryStream( 它甚至可以用于关闭的MemoryStream ),因为当前的DotNetZipLib中存在一个关于提取后关闭流的已知问题

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

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