大文件分页查询
当你在导入和解析Log文件的过程中,由于文件太大,文件大小一般的几百M甚至几个G的时间,一次性读取非常占用内存,
那么读取文件的时间就需要一定的技巧。
代码如下:
public class FileSegmentation { public FileStream EzoneStream { get; private set; } public long PageCount { get; private set; } public long PageSize = 1024; public long FileSize { get; private set; } public FileSegmentation(string filename) { FileInfo EzoneFile = new FileInfo(filename); EzoneStream = EzoneFile.OpenRead(); PageCount = (EzoneStream.Length / PageSize); FileSize = EzoneFile.Length; } public byte[] GetPage(Int64 pageNumber) { if (EzoneStream == null || !EzoneStream.CanSeek || !EzoneStream.CanRead) return null; if (pageNumber < 0 || pageNumber >= PageCount) return null; Int64 offsetStart = (Int64)pageNumber * (Int64)PageSize; Int64 offsetEnd = 0; if (pageNumber < PageCount - 1) offsetEnd = offsetStart + PageSize - 1; else offsetEnd = FileSize - 1; byte[] tmp = new byte[offsetEnd - offsetStart + 1]; EzoneStream.Seek(offsetStart, SeekOrigin.Begin); int rd = EzoneStream.Read(tmp, 0, (Int32)(offsetEnd - offsetStart + 1)); return tmp; } }
public class SymphonyReadLog : AsynchronousWorkBaseEx { private FileSegmentation Segmentation; public event ProgressBarEventHandler ProgressBarEvent; public long Count { get; private set; } public string Filter { get; set; } public SymphonyReadLog(string pathFile) { this.Segmentation = new FileSegmentation(pathFile); this.Count = this.Segmentation.PageCount; } public List<string> SecurityReadLog(ref string buffers, Int64 pageNum) { List<string> dataList = new List<string>(); string data = string.Empty; byte[] b = Segmentation.GetPage(pageNum); //解析文本 if (b != null) { data = buffers + ServiceConstEx.ServiceEncoding.GetString(b); string[] array = data.Split('\n'); foreach (var item in array) { if (item.IndexOf("\r") >= 0) { dataList.Add(item); } else { buffers = item; } } } return dataList; } /// 读取日志 public string ReadLog(string pathFile) { string message = string.Empty; long sumLength = 0; using (FileStream stream = new FileStream(pathFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { BinaryReader r = new BinaryReader(stream); sumLength = stream.Length; byte[] postArray = r.ReadBytes((int)sumLength); if (stream.CanRead) { int k = 1024; for (int i = 0; i < postArray.Length; i += k) { if (i + k > postArray.Length) { k = postArray.Length - i; } r.Read(postArray, i, k); } } message = ServiceConstEx.ServiceEncoding.GetString(postArray); r.Close(); r.Dispose(); } return message; } public List<string> SecuritySerchReadLog() { string buffers = string.Empty; List<string> dataList = new List<string>(); string data = string.Empty; for (int i = 1; i < Segmentation.PageCount; i++) { List<string> serList = SecurityReadLog(ref buffers, i); foreach (string serchString in serList) { if (serchString.IndexOf(Filter) >= 0) { dataList.Add(serchString); } } } return dataList; } protected override void Run() { string buffers = string.Empty; string data = string.Empty; for (int i = 0; i < this.Segmentation.PageCount - 1; i++) { var dataList = new List<string>(); var serList = this.SecurityReadLog(ref buffers, i); foreach (string serchString in serList) { if (serchString.IndexOf(Filter) >= 0) { dataList.Add(serchString); } } worker.ReportProgress(i + 1, dataList); } } protected override void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) { ProgressBarEventArgs arg = new ProgressBarEventArgs(e.ProgressPercentage, e.UserState); OnProgressBarEvent(arg); } protected void OnProgressBarEvent(ProgressBarEventArgs e) { if (this.ProgressBarEvent != null) { this.ProgressBarEvent(this, e); } } }