在 System.IO.TextWriter.WriteLine(String value) 抛出的 OutOfMemo



我有一个循环调用的方法,用于生成.c和.h文件,其内容由字符串模板确定。但是在生成大约>4000 个文件后,我遇到了内存不足异常。

在遵循堆栈跟踪后,我发现异常在 WriteLine 方法中抛出StreamWriter (System.IO.TextWriter.WriteLine(String value))生成的文件是:
- .c 文件 - 大约 4.5 – 6.5 MB 和 .h 文件 – 大约 5KB
- 有超过 4000 个文件被生成。
- 我也在里面使用流作家使用语句进行自动刷新

protected virtual void WriteFile ( string fileName, string content )
{
string directoryName = Path.GetDirectoryName ( fileName );
if ( Directory.Exists( directoryName ) == false )
{
Directory.CreateDirectory ( directoryName );
}
// ensure consistent line ending
using ( var sw = new StreamWriter ( fileName ) )
{
sw.WriteLine(EnsureWindowsStyleLineEnding(content));
}
}

private string EnsureWindowsStyleLineEnding(string content)
{
// convert all linux or mixed line endings (n) to windows line endings (rn)
// first ensure that all are linux
string linux = new StringBuilder(content).Replace("rn", "n").ToString();
// now convert all to windows
string windows = new StringBuilder(linux).Replace ("n", "rn").ToString();
return windows;
}

请建议如何解决此内存不足异常。

请查看下面是否有帮助。

private StringBuilder changeLineEnding = new StringBuilder();
private string EnsureWindowsStyleLineEnding(string content)
{
changeLineEnding.Clear();
// convert all linux or mixed line endings (n) to windows line endings (rn)
// first ensure that all are linux
changeLineEnding.Append(content);
changeLineEnding = changeLineEnding.Replace("rn", "n");
// now convert all to windows
changeLineEnding = changeLineEnding.Replace("n", "rn");
return changeLineEnding.ToString();
}

您正在执行大量字符串操作,并且分配的内存将由 GC 自行释放,这可能需要时间。

这是我建议的解决方案,只需逐行编写:

protected virtual void WriteFile ( string fileName, string content )
{
string directoryName = Path.GetDirectoryName ( fileName );
if ( Directory.Exists( directoryName ) == false )
{
Directory.CreateDirectory ( directoryName );
}
// ensure consistent line ending
using ( var sw = new StreamWriter ( fileName ) )
{
foreach (line in content.Split('n')) sw.WriteLine(line.Trim('r'));
}
}

尝试手动清除缓冲区:

using ( var sw = new StreamWriter ( fileName ) )
{
sw.WriteLine(EnsureWindowsStyleLineEnding(content));
sw.Flush(); // clear buffer manually 
}

最新更新