为现有StreamWriter代码添加压缩功能

本文关键字:添加 压缩 功能 代码 StreamWriter | 更新日期: 2023-09-27 18:25:28

我正在处理的程序当前正在使用StreamWriter在目标文件夹中创建一个或多个文本文件。在StreamWriter类之外,我通过Using指令(针对隐式.Close)使用WriteLine及其IDisposable接口。

我需要添加一个选项,在目标文件夹内的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。我们仍然需要支持在Windows2003上运行的客户端。

为现有StreamWriter代码添加压缩功能

使用StreamWriter(Stream)构造函数将其写入MemoryStream。将Position设置回0,这样您就可以使用ZipFile.save(Stream)将写入的文本保存到存档中。请查看项目示例代码中的ZipIntoMemory辅助方法以获取指导。

首先,使用.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();
                    }
                }
            }
        }