簡體   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