65.9K
CodeProject 正在变化。 阅读更多。
Home

如何使用 GZipStream 提取文本日志并将结果显示在网格中

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (2投票s)

2010年2月25日

CDDL

2分钟阅读

viewsIcon

29956

downloadIcon

330

使用 GZipStream 提取文本日志并在网格中列出结果。

引言

该程序的目的在于使用 GZipStream 完成以下任务:

  1. 使用 GzipStream 提取 .gz 文件中的所有文本文件
  2. 解析文本文件并将其添加到列表中
  3. 按日期筛选列表
  4. 使用 WPF 在网格中列出结果

背景

GZipStream 是用来做什么的?这是一个位于 System.IO.Compression 下的类,它提供了用于压缩和解压缩流的方法和属性。

数据说明

我们需要一种特定格式的文本日志。这是一个示例数据:

Bill, Campbelltown, IceMan1, 2010-02-18
Steve, Campbelltown, IceMan, 2010-02-18
Vioc, Townhall, Spiderman, 2010-02-18

使用代码

GZipStreamProject 包含一个 C# 类库 GZipCore,其中包含以下类:GZipModelGzipBusiness

GZipModel 具有所有属性声明,我们稍后将使用这些属性从文本日志中添加数据。

public class GZipModel
{
   public string Name { get; set; } 
   public string Address { get; set; } 
   public string Signature { get; set; } 
   public DateTime Date { get; set; } 
}

GZipBusiness:在这个类中,我们拥有所有压缩和解压缩、解析文件以及返回 GZipModel 类型列表对象的模型方法。

我使用了 System.IOSysten.IO.Compression API 来处理文件系统。我们首先获取源文件的流,并添加一个 'if' 条件来防止压缩隐藏的和已经压缩的带有 .gz 扩展名的文件。

static void Compress(FileInfo fi)
{
    // Get the stream of the source file.
    using (FileStream inFile = fi.OpenRead())
    {
        // Prevent compressing hidden and already compressed files.
        if ((File.GetAttributes(fi.FullName) & FileAttributes.Hidden)
                        != FileAttributes.Hidden & fi.Extension != ".gz")
        {
            // Create the compressed file.
            using (FileStream outFile = File.Create(fi.FullName + ".gz"))
            {
                using (GZipStream Compress = new GZipStream(outFile,
                               CompressionMode.Compress))
                {
                    // Copy the source file into the compression stream.
                    byte[] buffer = new byte[4096];
                    int numRead;
                    while ((numRead = inFile.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        Compress.Write(buffer, 0, numRead);
                    }
                    Console.WriteLine("Compressed {0} from {1} to {2} bytes.",
                    fi.Name, fi.Length.ToString(), outFile.Length.ToString());
                }
            }
        }
    }
}

在这个用于解压缩 .gz 文件的函数中,我们从源文件获取流。它将获取原始文件的扩展名,并将文件解压缩到选定的目录。

static void Decompress(FileInfo fi)
{
    // Get the stream of the source file.
    using (FileStream inFile = fi.OpenRead())
    {
        // Get original file extension, for example "doc" from report.doc.gz.
        string curFile = fi.FullName;
        string origName = curFile.Remove(curFile.Length - fi.Extension.Length);
    
        //Create the decompressed file.
        using (FileStream outFile = File.Create(origName))
        {
            using (GZipStream Decompress = new GZipStream(inFile,
            CompressionMode.Decompress))
            {
                //Copy the decompression stream into the output file.
                byte[] buffer = new byte[4096];
                int numRead;
                while ((numRead = Decompress.Read(buffer, 0, buffer.Length)) != 0)
                {
                    outFile.Write(buffer, 0, numRead);
                }
                Console.WriteLine("Decompressed: {0}", fi.Name);
            }
        }
    }
}

然后,我们解析提取的文件并将其添加到列表集合中。此方法还将通过分配要从提取的文件中删除的“分隔符字符”来清理数据,并使用“拆分方法”将字符串转换为包含文本日志数据每一行的子字符串的数组。

static List<gzipmodel> ParseFile(string path)
{
    DirectoryInfo dir = new DirectoryInfo(path);

    char[] delim = { ' ', '\t','\r','\n', '\\'};

    List<gzipmodel> listinfo = new List<gzipmodel>();

    foreach (FileInfo fi in dir.GetFiles("*.txt"))
    {
        using (StreamReader sr = new StreamReader(fi.FullName) )
        {
            String line;
            
            // Read and display lines from the file until the end of 
            // the file is reached.
            while ((line = sr.ReadLine()) != null) 
            {
                string[] data = line.Split(delim);

                GZipModel model = new GZipModel();
                if (data[0] != "")
                {
                    model.Name = data[0].ToString();
                    model.Address = data[1].ToString();
                    model.Signature = data[2].ToString();
                    string dtString = data[3].ToString();
                    DateTime Date = DateTime.Parse(dtString);
                    model.Date = Date;

                    listinfo.Add(model);
                }
            }
        }
    }
    return listinfo;
}

以下是公共方法调用,用于返回类型为 GZipModelList。我还使用 lambda 表达式过滤数据,以获取文本日志中的所有星期四记录。

public static List<gzipmodel> Model(string path)
{
    List<gzipmodel> model = new List<gzipmodel>();

    // Path to directory of files to compress and decompress.
    string dirpath = path;

    DirectoryInfo di = new DirectoryInfo(dirpath);

    // Compress the directory's files.
    foreach (FileInfo fi in di.GetFiles())
    {
        Compress(fi);
    }

    // Decompress all *.gz files in the directory.
    foreach (FileInfo fi in di.GetFiles("*.gz"))
    {
        Decompress(fi);
    }

    List<gzipmodel> data = ParseFile(dirpath);
    GZipModel mode = new GZipModel();

    /// This will get all the data in thursday
    var query = from n in data.Where(o => o.Date.DayOfWeek ==  
                                     DayOfWeek.Thursday )
                select n;
    return query.ToList();
}

添加一个名为 GZipUI 的 WPF 应用程序项目,它将创建两个 XAML 文件:ap.xamlwindow1.xaml。删除 Window1.xaml 文件并添加一个新窗口,命名为 Main.xaml。现在,我们需要更新 App.xaml 中的 StartupURI 以指向 Main.xaml

您需要在 GZipUI 中引用 WPFToolkit。从以下网址下载 WPF Toolkit:http://wpf.codeplex.com/releases/view/29117

我在 Main.xaml 中有两个事件:btnBrowse_Click 用于选择日志数据文件路径,而 btnExtract_Click 将调用 GZipBusiness.Model 以从列表中获取数据。

此外,您需要引用 System.Windows.Forms 才能使用 FolderBrowserDialog API。

private void btnExtract_Click(object sender, RoutedEventArgs e)
{
   var list = GZipCore.GZipBusiness.Mode(
                       this.textWebsiteRootPath.Text);
   gridList.ItemsSource = list;
}

private void btnBrowse_Click(object sender, RoutedEventArgs e)
{
    var browser = new System.Windows.Forms.FolderBrowserDialog
    {
                RootFolder = Environment.SpecialFolder.MyComputer,
                SelectedPath = this.textWebsiteRootPath.Text,
    };

    var result = browser.ShowDialog();
    if (result == System.Windows.Forms.DialogResult.OK)
    {
                this.textWebsiteRootPath.Text = browser.SelectedPath;
    }
}

gzipui.JPG

历史

  • 2010/02/26 - 添加文章。
© . All rights reserved.