2013-07-29 40 views
0

我正在使用的程序當前使用StreamWriter在目標文件夾中創建一個或多個文本文件。關閉StreamWriter類,我正在使用WriteLine及其IDisposable接口通過Using指令(隱含.Close)。向現有的StreamWriter代碼添加壓縮功能

我需要添加一個選項來創建一個或多個文本文件在目標文件夾內的zip存檔文件中。我打算將現有代碼更改爲使用流,因此可以使用ZIP文件作爲輸出(計劃使用DotNetZip)。

我想創建一些GetOutputStream函數並將其饋入到當前存在的方法中。該功能將確定是否設置了存檔選項,並創建純文件或將其歸檔。問題是MemoryStream看起來好像是一個很好的緩衝區類,與DotNetZip一起使用,與繼承層次結構中的StreamWriter不相交。

看起來像我唯一的選擇是創建一些IWriteLine接口,它將執行WriteLineIDisposable。然後分別從StreamWriterMemoryStream分支兩個新的子類,並在其中實施IWriteLine

有沒有更好的解決方案?

當前的代碼概念性地看起來像這樣:

Using sw As StreamWriter = File.CreateText(fullPath) 
    sw.WriteLine(header) 
    sw.WriteLine(signature) 
    While dr.Read 'dr=DataReader 
    Dim record As String = GetDataRecord(dr) 
    sw.WriteLine(record) 
    End While 
End Using 

對於代碼樣本,無論是VB.NETC#優良,儘管這更是一個概念上的問題。

編輯:不能使用.NET 4.5的System.IO.Compression.ZipArchive,必須堅持.NET 4.0。我們仍然需要支持在Windows 2003上運行的客戶端。

+0

我不是在追問爲什麼'StreamWriter'和'MemoryStream'需要一個共同的祖先。 –

+0

@KeithPayne:能夠通過共同的祖先類型返回。與使用textboxbase類處理常規和帶有掩碼的文本框類似。 – Neolisk

+0

在你想要完成的事情中,是否有理由?我只問,因爲這兩種類型,'StreamWriter'和'MemoryStream',沒有什麼共同之處。它們之間相互關聯的唯一原因是'StreamWriter'可以將字節寫入'MemoryStream'(或者'FileStream')。 –

回答

1

使用的StreamWriter(流)構造函數將它寫入一個MemoryStream。將位置設回0,以便您可以使用ZipFile.Save(Stream)將寫入的文本保存到存檔中。檢查項目sample code中的ZipIntoMemory幫助器方法以獲取指導。

+0

+1。這看起來很有趣 - 謝謝。我會看看。 – Neolisk

+0

直到'ZipFile.Save(Stream)'爲止,它會將整個文件內容保存在內存中嗎?這些文件的大小可能相當大。 – Neolisk

+0

這是垃圾收集器的工作,而不是ZipFile的工作。 「相當大」當然是實際使用文件而不是MemoryStream的一個很好的理由。 –

1

首先,對於.NET 4.5 System.IO.Compression.ZipArchive類(請參閱http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive.aspx),您不再需要DotNetZip至少用於常見的壓縮任務。

它看起來是這樣的:

 string filePath = "..."; 

     //Create file. 
     using (FileStream fileStream = File.Create(filePath)) 
     { 
      //Create archive infrastructure. 
      using (ZipArchive archive = new ZipArchive(fileStream, ZipArchiveMode.Create, true, Encoding.UTF8)) 
      { 
       SqlDataReader sqlReader = null; 

       //Reading each row into a separate text file in the archive. 
       while(sqlReader.Read()) 
       { 
        string record = sqlReader.GetString(0); 

        //Archive entry is a file inside archive. 
        ZipArchiveEntry entry = archive.CreateEntry("...", CompressionLevel.Optimal); 

        //Get stream to write the archive item body. 
        using (Stream entryStream = entry.Open()) 
        { 
         //All you need here is to write data into archive item stream. 
         byte[] recordData = Encoding.Unicode.GetBytes(record); 
         MemoryStream recordStream = new MemoryStream(recordData); 
         recordStream.CopyTo(entryStream); 

         //Flush the archive item to avoid data loss on dispose. 
         entryStream.Flush(); 
        } 
       } 
      } 
     } 
+0

不幸的是,我不能使用.NET 4.5。我會將此信息添加到問題中。 – Neolisk