2013-12-11 2 views
1

Мне нужно добавить много строк в цикле, и это создаст очень длинную строку.
1GB должна быть достаточно длинной, чтобы хранить строку, поэтому я делаю это:sb = new StringBuilder (1024 * 1024 * 1024)> 'System.OutOfMemoryException' был сброшен

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

Похоже, что ваш JVM не настроен на доступ к 2 гигабайтам памяти (1G символов == 2 ГБ). – dasblinkenlight

+2

JVM? Это вопрос C#. – Nuzzolilo

ответ

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); 
    } 
} 

`

Ссылки: What consumes less resources and is faster File.AppendText or File.WriteAllText storing first in StringBuilder?

+0

Обновлен код. Удивительно, как на одного лайнера остается больше всего голосов. – Nuzzolilo

6

Используйте файловый поток для записи длинных файлов. Нет необходимости хранить всю строку в памяти в любой момент времени.

4

Вы не просили StringBuilder с достаточной емкостью для хранения 1 ГБ - вы просили один с достаточной емкостью для хранения 1024 * 1024 * 1024 символа, что потребует (примерно) 2 ГБ памяти. Это меньше максимальной длины строки (2^31-1 символов), но больше объема кучи, доступного в 32-битном процессе.

Вам может не понадобиться StringBuilder с такой способностью - другие ответы обсуждают это. Предполагая, что вам нужна строка, гигантская, вам определенно не нужно предварительно выделять свой StringBuilder с этим размером. Просто создать StringBuilder, и пусть это grow on its own:

var sb = new StringBuilder(); 

или предварительно выделить что-то более разумным, если вы знаете, вы будете иметь огромное количество данных:

var sb = new StringBuilder(1024 * 1024); 
Смежные вопросы