如何使用 GZipStream 提取文本日志并将结果显示在网格中
使用 GZipStream 提取文本日志并在网格中列出结果。
引言
该程序的目的在于使用 GZipStream
完成以下任务:
- 使用 GzipStream 提取 .gz 文件中的所有文本文件
- 解析文本文件并将其添加到列表中
- 按日期筛选列表
- 使用 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,其中包含以下类:GZipModel
和 GzipBusiness
。
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.IO
和 Systen.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;
}
以下是公共方法调用,用于返回类型为 GZipModel
的 List
。我还使用 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.xaml 和 window1.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;
}
}
历史
- 2010/02/26 - 添加文章。