Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> StringBuilder и OutOfMemoryException 
:(
    Опции темы
m9yt
Дата 14.4.2012, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 27.2.2010

Репутация: нет
Всего: нет



Привет всем. Делаю небольшой текстовый редактор и натолкнулся на следующую проблему:
при загрузке достаточно большого файла через StringBuilder вылетает OutOfMemoryException, что логично. Но, пытаясь вызвать метод Clear() у объекта StringBuilder, вновь вылетает то же исключение. Что за дела? Не могу очистить память от большого файла.
Код

private void OpenMenuItemClick(object sender, EventArgs e)
{
    openFileDialog.FileName = String.Empty;
    if( openFileDialog.ShowDialog() != DialogResult.OK )
        return;
    filePath = openFileDialog.FileName;
    var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    var reader = new StreamReader(fileStream, Encoding.Default);
    var buf = new StringBuilder();
    try
    {
        while(!reader.EndOfStream)
        {
            buf.AppendLine(reader.ReadLine());
        }
        textBox.Text = buf.ToString();
        var fileInfo = new FileInfo(filePath);
        Text = string.Format("{0} — TextEditor", fileInfo.Name);
    }
    catch (OutOfMemoryException)
    {
        MessageBox.Show("Недостаточно памяти для загрузки файла!", "Ошибка приложения", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    catch (Exception exc)
    {
        MessageBox.Show(exc.Message, "Ошибка приложения", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    finally
    {
        buf.Clear();// тут - то и вылетает повторно OutOfMemoryException, если я пытался загрузить большой файл
        reader.Close();
        fileStream.Close();
    }
}

PM MAIL   Вверх
dextermd
Дата 14.4.2012, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 35
Регистрация: 21.6.2008

Репутация: нет
Всего: нет



Данный метод можно упростить следующим образом:
1) Выкинуть FileStream;
2) Вместо StringBuilder'a использовать метод ReadToEnd() из класса StreamReader;
3) Вместо блока finally обернуть StreamReader в блок using, таким образом после завершения работы StreamReader'a все ресурсы освободятся автоматически;
4) Для определения имени файла использовать статический метод Path.GetFileName().

Код

private void OpenMenuItemClick(object sender, EventArgs e)
{
    openFileDialog.FileName = String.Empty;
    if (openFileDialog.ShowDialog() != DialogResult.OK)
        return;
    filePath = openFileDialog.FileName;

    using (StreamReader reader = new StreamReader(filePath, Encoding.Default))
    {
        try
        {
            textBox.Text = reader.ReadToEnd();
            Text = string.Format("{0} — TextEditor", Path.GetFileName(filePath));
        }
        catch (OutOfMemoryException)
        {
            MessageBox.Show("Недостаточно памяти для загрузки файла!", "Ошибка приложения", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.Message, "Ошибка приложения", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}



Это сообщение отредактировал(а) dextermd - 14.4.2012, 20:45
PM MAIL   Вверх
erm0l0v
Дата 17.4.2012, 08:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 11.1.2011

Репутация: 1
Всего: 1



Вы не можете разместить в памяти файл произвольного размера. В Notepad например помойму файлы разметом 13+ МБ вообще не загружаются.
Если вы хотите сделать редактор который сможет редактировать любые файлы придется загружать их по блокам. Но тут встает вопрос с освобождением памяти, как C# будет память освобождать это большая загадка. Метод Clear  совсем не обязан освободить память он только закрывает ресурсы.
PM MAIL   Вверх
jonie
Дата 17.4.2012, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



Цитата(erm0l0v @  17.4.2012,  09:26 Найти цитируемый пост)
Если вы хотите сделать редактор который сможет редактировать любые файлы придется загружать их по блокам. Но тут встает вопрос с освобождением памяти, как C# будет память освобождать это большая загадка

гуглить про MemoryMapedFiles попробуйте - оно поможет жить...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0572 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.