我需要在循环中附加大量字符串,这将创建一个非常长的字符串。
1GB应足够长以存储字符串,因此我这样做:
var sb = new StringBuilder(1024 * 1024 * 1024);
但收到此错误
'System.OutOfMemoryException' was thrown
任何追加长字符串的建议吗?
我正在为MySQL数据库编写备份工具。这些工具将从数据库导出数据并写入文本文件。数据包含BLOB和TEXT数据类型。所以,期待很长的字符串。
这是代码:代码更新1
var conn = new MySqlConnection(Program.ConnectionString);
var cmd = new MySqlCommand();
cmd.Connection = conn;
conn.Open();
cmd.CommandText = selectSQL;
MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
var sb = new StringBuilder(1024 * 1024 * 1024);
for (int i = 0; i < rdr.FieldCount; i++)
{
if (sb.Length > 0)
sb.AppendFormat(separator);
if (rdr[i].GetType() == typeof(byte[]))
{
sb.AppendFormat(ConvertByteArrayToHexString((byte[])rdr[i]));
}
else
sb.AppendFormat(rdr[i] + "");
}
WriteToFile(sb.ToString());
}
conn.Close();
答案 0 :(得分:6)
使用文件流编写长文件。任何时候都不需要将完整的字符串保留在内存中。
答案 1 :(得分:4)
根据Windows虚拟内存的方式以及.NET运行时的工作原理,内存不足错误可能由多种原因引起。
你真的需要一次将所有内容都转储到StringBuilder中吗?如果您正在写入文件,则可以一次分段操作。
使用类似的东西作为起点: int bufferSize = 65536;
using (StreamWriter sw = new StreamWriter("filename", true, System.Text.Encoding.UTF8, bufferSize))
{
while(!finished)
{
string data = "foo"; //get next data here...
sw.Write(data);
}
}
`
答案 2 :(得分:4)
你没有要求StringBuilder有足够的容量来存储1 GB - 你已经要求一个有足够容量存储1024 * 1024 * 1024字符的字符串,这需要(大约)2 GB的内存。它小于最大字符串长度(2 ^ 31-1个字符),但大于32位进程中可用的堆空间。
您可能不需要具有这种容量的StringBuilder - 其他人的答案也在讨论这个问题。假设您需要一个巨大的字符串,您绝对不需要预先分配具有该大小的StringBuilder。只需创建一个StringBuilder,然后让它grow on its own:
var sb = new StringBuilder();
或预先分配更合理的内容,如果您知道您将拥有大量数据:
var sb = new StringBuilder(1024 * 1024);