内存不足错误归档日志文件

我遇到了运行控制台作业的问题,并创建了我在午夜归档的每日日志文件。

这将为第二天创建一个空白日志文件,并在名称和旧文件的内容中创建一个带有昨天日期的归档文件,用于调试我可能已经知道的问题,直到第二天才知道。

但是,当我尝试归档文件时,由于我加快了BOT的工作,我遇到了System Out of Memory错误的问题。

起初我根本无法获得一个存档文件然后我找到了一种方法来获得至少最后的100,000行,这还不够。

我把所有东西都包裹在3次尝试/捕获中

  1. I / O
  2. 系统内存不足
  3. 标准例外

但是,我总是得到OutOfMemoryException,例如

System.OutOfMemoryException错误:抛出了类型’System.OutOfMemoryException’的exception。

举个例子,大小为100,000行的日志大约是11MB文件

标准的完整日志文件可以是1/2 GB到2 GB的任何内容

我需要知道的是:

a)当尝试使用File.ReadAllText或我调用ReadFileString的自定义StreamReader函数时,标准文本文件的大小会引发内存不足错误,例如

public static string ReadFileString(string path) { // Use StreamReader to consume the entire text file. using (StreamReader reader = new StreamReader(path)) { return reader.ReadToEnd(); } } 

b)是我的计算机内存(我有16GB内存 – 复制时使用8GB)或我在C#中使用的文件打开和复制失败的对象。

归档时我首先尝试使用我的自定义ReadFileString函数(见上文),如果返回0字节的内容我尝试File.ReadAllText然后如果失败我尝试自定义函数来获取最后100,000行,这实际上是不够的在当天早些时候调试错误。

日志文件在午夜开始创建新日志并记录全天。 我从来没有过去的内存错误,但由于我已经调高了方法调用的频率,日志记录已经扩展,这意味着文件大小也有。

这是我获取最后100,000行的自定义函数。 我想知道在没有IT丢失内存错误的情况下我可以获得多少行,并且我根本没有得到最后几天日志文件的任何内容。

人们建议保持X行所需的各种方法/内存的最大文件大小,以及获取尽可能多的日志文件的最佳方法是什么?

EG以某种方式逐行循环,直到遇到exception,然后保存我所拥有的内容。

这是我的GetHundredThousandLines方法,它记录到一个非常小的调试文件,这样我就可以看到在归档过程中发生了什么错误。

 private bool GetHundredThousandLines(string logpath, string archivepath) { bool success = false; int numberOfLines = 100000; if (!File.Exists(logpath)) { this.LogDebug("GetHundredThousandLines - Cannot find path " + logpath + " to archive " + numberOfLines.ToString() + " lines"); return false; } var queue = new Queue(numberOfLines); using (FileStream fs = File.Open(logpath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (BufferedStream bs = new BufferedStream(fs)) // May not make much difference. using (StreamReader sr = new StreamReader(bs)) { while (!sr.EndOfStream) { if (queue.Count == numberOfLines) { queue.Dequeue(); } queue.Enqueue(sr.ReadLine() + "\r\n"); } } // The queue now has our set of lines. So print to console, save to another file, etc. try { do { File.AppendAllText(archivepath, queue.Dequeue(), Encoding.UTF8); } while (queue.Count > 0); } catch (IOException exception) { this.LogDebug("GetHundredThousandLines - I/O Error accessing daily log file with ReadFileString: " + exception.Message.ToString()); } catch (System.OutOfMemoryException exception) { this.LogDebug("GetHundredThousandLines - Out of Memory Error accessing daily log file with ReadFileString: " + exception.Message.ToString()); } catch (Exception exception) { this.LogDebug("GetHundredThousandLines - Exception accessing daily log file with ReadFileString: " + exception.Message.ToString()); } if (File.Exists(archivepath)) { this.LogDebug("GetHundredThousandLines - Log file exists at " + archivepath); success = true; } else { this.LogDebug("GetHundredThousandLines - Log file DOES NOT exist at " + archivepath); } return success; } 

任何帮助将非常感激。

谢谢

尝试:保持队列和流在类范围内的位置,在内存不足和再次调用函数时尝试GC.Collect()。 寻求流到最后的位置并继续。 或:使用一个数据库,如sqlite,并在每个表中保留最新的100000记录。