我在运行控制台作业时遇到问题,该作业运行并创建我在午夜存档的每日日志文件。
这将创建一个第二天的空白日志文件和一个存档文件,其中名称中包含昨天的日期以及旧文件的内容,用于调试我可能遇到但直到第二天才知道的问题。
然而,自从我启动 BOT 的工作以来,当我尝试归档文件时,我一直遇到系统内存不足错误的问题。
起初我根本无法获取存档文件,然后我找到了一种方法来获取至少最后 100,000 行,但这还远远不够。
我将所有内容包装在 3 个 try/catch 中
- I/O
- 系统内存不足
- 标准例外
然而,我得到的总是 OutOfMemoryException,例如
System.OutOfMemoryException 错误:抛出了“System.OutOfMemoryException”类型的异常。
举个例子,大小为 100,000 行的日志大约为 11MB 文件
标准完整日志文件可以是 1/2 GB 到 2GB 之间的任何内容
我需要知道的是:
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 RAM - 复制时使用了 8GB)还是我在 C# 中使用的对象在打开和复制文件时失败了。
归档时,我首先尝试使用自定义 ReadFileString 函数(见上文),如果返回 0 字节的内容,我会尝试 File.ReadAllText,然后如果失败,我会尝试自定义函数来获取最后 100,000 行,这对于当天早些时候调试错误。
日志文件在创建新日志文件时于午夜开始并记录一整天。我以前从未遇到过内存不足错误,但由于我调高了方法调用的频率,日志记录已扩展,这意味着文件大小也已扩展。
这是我的自定义函数,用于获取最后 100,000 行。我想知道在 IT 不会抛出内存不足错误的情况下我可以获得多少行,并且我根本没有获得最近几天日志文件的任何内容。
人们对保存 X 行所需的各种方法/内存的最大文件大小有何建议,以及获取尽可能多的日志文件的最佳方法是什么?
例如,某种方式逐行循环,直到遇到异常,然后保存我所拥有的内容。
这是我的 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<string>(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;
}
任何帮助将非常感激。
Thanks