限制 txt 文件的行数
本文关键字:文件 txt 限制 | 更新日期: 2023-09-27 18:32:29
我有一个文本文件,我使用 WriteLineAsync 方法每 30 分钟保存一行。当文件变得太大时,如果我尝试读取它,应用程序就会崩溃。我认为我可以限制文件上可写的行,因此当我添加新行时,将删除最旧的行。我该怎么做?
编辑:我使用以下代码读取文件:
StorageFile MyFile = await ApplicationData.Current.LocalFolder.GetFileAsync("LogFile.txt");
string nextLine;
using (StreamReader reader = new StreamReader(await MyFile.OpenStreamForReadAsync()))
{
while ((nextLine = await reader.ReadLineAsync()) != null)
{
TextLog.Text += nextLine + "'n";
}
}
我尝试调试它,但我在阅读代码中没有得到任何异常。也许问题是我试图将所有文本放在文本块中。
如果您确实需要对文本文件执行此操作,则必须执行以下操作之一:
- 将整个文件读入内存,切掉不需要的部分,然后将其写回
- 逐行读取文件,忽略前 X 行以低于阈值,将您想要的行写到临时文件中。过滤完所需的所有行后,将临时文件移动到现有文件的顶部。
还有其他选择:
- 使用支持任意删除的文件格式/数据结构,例如数据库。
- 使用滚动日志,在现有文件变得太大时启动一个新文件。有许多现有的日志记录库只需进行一些配置即可开箱即用。
- 停止读取整个文件,只读取其末尾。当然,这既有好处也有缺点。好处是您可以根据需要保持文件的大小。缺点是,如果您需要保证读取最后 N 行,那么需要更多的工作来确保这一点。
如果您知道需要记录的行的最大长度,并且不介意从日志字符串中修剪 null,则以下解决方案可能适合您。
这是一个简单的想法,您可以在其中创建一个知道最大大小的空文件,并在每次写入的当前位置写入最大字节行长度。当您到达末尾时,您只需循环回文件的开头 - 这意味着您将在下次写入时覆盖第一个也是最旧的条目。
class MyWriter : IDisposable
{
BinaryWriter _writer;
readonly int _maxLineLength, _maxLines, _size;
public MyWriter(string path, int maxLineLength, int maxLines)
{
_maxLineLength = maxLineLength;
_maxLines = maxLines;
_size = _maxLineLength * _maxLines;
_writer = new BinaryWriter(File.Create(path));
_writer.BaseStream.SetLength(_size);
}
public void Write(string str)
{
if (str.Length > _maxLineLength) throw new ArgumentOutOfRangeException();
// Write the string to the current poisition in the stream.
// Pad the rest of the line with null.
_writer.Write(str.PadRight(_maxLineLength, ''0').ToCharArray());
// If the end of the stream is reached, simply loop back to the start.
// The oldest entry will then be overwritten next.
if (_writer.BaseStream.Position == _size)
_writer.Seek(0, SeekOrigin.Begin);
}
public void Dispose()
{
if(_writer != null)
_writer.Dispose();
}
}
可能用作:
using(var writer = new MyWriter("MyFile.txt", 200, 100))
{
writer.Write("Hello World!");
}