У меня проблема с консольным заданием, которое запускается и создает файл ежедневного журнала, который я архивирую в полночь.
Это создает пустой файл журнала на следующий день и заархивированный файл со вчерашней датой в имени и содержимым старого файла для отладки проблем, которые у меня могли быть и о которых я не знал до следующего дня.
Однако с тех пор, как я запустил работу BOT, у меня возникали проблемы с ошибками System Out of Memory, когда я пытался архивировать файл.
Сначала я просто не мог получить заархивированный файл, затем я придумал способ получить хотя бы последние 100 000 строк, чего явно недостаточно.
Я оборачиваю все в 3 попытки/уловы
- I/O
- Системе не хватает памяти
- стандартное исключение
Однако я всегда получаю исключение OutOfMemoryException, например
Ошибка System.OutOfMemoryException: было создано исключение типа «System.OutOfMemoryException».;
Чтобы дать вам пример размера 100 000 строк журнала, это файл размером около 11 МБ.
Стандартный полный файл журнала может иметь размер от 1/2 ГБ до 2 ГБ.
Мне нужно знать следующее:
а) какой размер стандартного текстового файла вызовет ошибку нехватки памяти при попытке использовать File.ReadAllText или пользовательскую функцию StreamReader, которую я вызываю ReadFileString, например
public static string ReadFileString(string path)
{
// Use StreamReader to consume the entire text file.
using (StreamReader reader = new StreamReader(path))
{
return reader.ReadToEnd();
}
}
б) это память моего компьютера (у меня 16 ГБ ОЗУ - 8 ГБ используется во время копирования) или объекты, которые я использую в С#, не работают при открытии и копировании файлов.
При архивировании я сначала пытаюсь использовать свою пользовательскую функцию ReadFileString (см. выше), если она возвращает 0 байтов содержимого, я пробую File.ReadAllText, а затем, если это не удается, я пробую пользовательскую функцию, чтобы получить последние 100 000 строк, чего действительно недостаточно для отладки ошибок ранее в тот же день.
Файл журнала начинается в полночь, когда создается новый, и регистрируется в течение всего дня. Раньше у меня никогда не было ошибок нехватки памяти, но с тех пор, как я увеличил частоту вызовов методов, ведение журнала расширилось, что означает, что размеры файлов также увеличились.
Это моя пользовательская функция для получения последних 100 000 строк. Мне интересно, сколько строк я мог бы получить без того, чтобы ИТ-специалист выдал ошибку нехватки памяти, а я вообще не получил никакого содержимого файла журнала последних дней.
Что люди предлагают для максимального размера файла для различных методов/памяти, необходимой для хранения строк 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;
}
Любая помощь приветствуется.
Спасибо