Streamwriter не записывает в файл

Обновлено: 02.07.2024

Я делаю редактор уровней для своей игры, и большая его часть работает, за исключением . Когда я пытаюсь сохранить свой файл (XML), файл не создается, и в поле вывода я получаю:

A first chance exception of type 'System.NullReferenceException'

Забавно то, что это происходит только в том случае, если файл не существует, но он работает правильно, если я перезаписываю другой файл.

вот код, который я использую:

data - строка (это не проблема, потому что она работает, когда я перезаписываю файл)

Какая строка дает NullReferenceException ? - ChrisF

Единственное, о чем я могу думать, это то, что у программы нет прав на создание каталога. Попробуйте удалить using (только для целей отладки) и посмотрите, не получите ли вы более значимое исключение. - ChrisF

@ChrisF нет, исключение все еще не появляется, оно просто записывается в поле вывода - annonymously

@luisperezphd да, они работают, если файл существует - annonymously

4 ответы

Вы отсутствует конструктор который принимает логическое значение, которое может помочь в создании файла:

Однако логика на самом деле немного сложнее:

public StreamWriter( string path, bool append )

Определяет, нужно ли добавлять данные в файл. Если файл существует, а добавление ложно, файл перезаписывается. Если файл существует и параметр append имеет значение true, данные добавляются к файлу. В противном случае создается новый файл.

Ну, это заставляет поток добавляться к файлу, я хочу заменить файл - анонимно

Если файл существует, я хочу перезаписать его, а не добавлять к нему - анонимно

Не думаю, что это правильная перегрузка. Проблема не в том, что файл перезаписывается, а в том, что он вообще не создается. - ChrisF

@ChrisF Я посмотрел и с append не являетесь false этот конструктор всегда будет создавать файл, если он не существует. Согласно это: Инициализирует новый экземпляр класса StreamWriter для указанного файла по указанному пути, используя кодировку по умолчанию и размер буфера. Если файл существует, его можно либо перезаписать, либо добавить к нему. Если файл не существует, этот конструктор создает новый файл. - Грант Томас

При использовании using ключевое слово, звонить не нужно sw.Close() , об этом позаботятся автоматически. (в этом весь смысл использования using в первую очередь) - Aevitas

Почему бы вам просто не обойти это простым способом и проверить наличие файла перед тем, как писать в него:

Я действительно не стал бы усложнять это лично. Также не закрывайте StreamWriter , using оператор удаляет его после того, как он выполнил свою задачу.

Однако проверка является избыточной, поэтому по своей сути усложняет задачу. - Грант Томас

Лично я так не думаю. Несмотря на то, что он может быть избыточным, он упрощает чтение, понимание и отладку. - Aevitas

В моем случае я запускал программу как не администратор, файл должен был быть записан внутри папки, созданной с правами администратора (даже внутри ProgramFiles или в любом месте, не являющемся администратором). Файл никогда не создается, и вам нужно вручную включить Managed Debugging Assistants исключение прерывается, чтобы увидеть любую ошибку.

Решение заключалось в том, чтобы удалить папку и создать ее снова с моей учетной записью без прав администратора. Также обратите внимание, что StreamWriter не создавать деревья каталогов, только файлы.

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

Записывает данные в поток.

Перегрузки

Записывает форматированную строку в поток, используя ту же семантику, что и метод Format(String, Object, Object, Object).

Записывает отформатированную строку в поток, используя ту же семантику, что и Format(String, Object, Object) метод.

Записывает в поток дочерний массив символов.

Записывает форматированную строку в поток, используя ту же семантику, что и метод Format(String, Object[]).

Записывает в поток массив символов.

Записывает в поток строку.

Записывает диапазон символов в поток.

Записывает символ в поток.

Записывает форматированную строку в поток, используя ту же семантику, что и метод Format(String, Object).

Write(String, Object, Object, Object)

Записывает форматированную строку в поток, используя ту же семантику, что и метод Format(String, Object, Object, Object).

Параметры

Строка составного формата.

Первый объект для форматирования и записи.

Второй объект для форматирования и записи.

Третий объект для форматирования и записи.

Комментарии

Write(String, Object, Object, Object)Описание доступных возможностей составного форматирования см. в разделе.

Применяется к

Write(String, Object, Object)

Записывает отформатированную строку в поток, используя ту же семантику, что и Format(String, Object, Object) метод.

Параметры

Строка составного формата.

Первый объект для форматирования и записи.

Второй объект для форматирования и записи.

Комментарии

Write(String, Object, Object)Описание доступных возможностей составного форматирования см. в разделе.

Применяется к

Write(Char[], Int32, Int32)

Записывает в поток дочерний массив символов.

Параметры

Массив символов, содержащий записываемые данные.

Положение символа в буфере, с которого начинается чтение данных.

Наибольшее количество символов для записи.

Исключения

buffer имеет значение null .

Длина буфера минус index меньше count .

index или count является отрицательным значением.

AutoFlush имеет значение True, или буфер StreamWriter полон, и текущее средство записи закрывается.

AutoFlush имеет значение True, или буфер StreamWriter полон, и его содержимое не может быть записано в основной поток заданного размера, поскольку StreamWriter находится в конце потока.

Примеры

Этот пример записывает восемь символов из 13-элементного массива в файл, начиная с третьего элемента массива.

Комментарии

Этот метод переопределяет метод TextWriter.Write.

Символы считываются с buffer начала index и продолжаются через index + ( count -1). Все символы записываются в базовый поток, если только конец базового потока не достигнут преждевременно. Flush вызывается автоматически, если AutoFlush имеет значение true .

Список общих задач ввода-вывода см. в разделе Общие задачи ввода-вывода.

См. также раздел

Применяется к

Write(String, Object[])

Записывает форматированную строку в поток, используя ту же семантику, что и метод Format(String, Object[]).

Параметры

Строка составного формата.

Массив объектов, содержащий от нуля и более объектов, которые необходимо форматировать и записать.

Комментарии

Write(String, Object[])Описание доступных возможностей составного форматирования см. в разделе.

Применяется к

Write(Char[])

Записывает в поток массив символов.

Параметры

Массив символов, содержащий записываемые в поток данные. Если buffer имеет значение null , запись не выполняется.

Исключения

AutoFlush имеет значение True, или буфер StreamWriter полон, и текущее средство записи закрывается.

AutoFlush имеет значение True, или буфер StreamWriter полон, и его содержимое не может быть записано в основной поток заданного размера, поскольку StreamWriter находится в конце потока.

Комментарии

Этот метод переопределяет метод TextWriter.Write.

Указанные символы записываются в базовый поток, если только конец потока не достигнут преждевременно. Если AutoFlush имеет значение true , Flush вызывается автоматически.

Этот метод может обеспечить более высокую производительность Write , чем ( char[],``int,``int ), так как в нем меньше аргументов для проверки.

//открой нативно
FileStream _sn = new FileStream("myfile.txt", FileMode.OpenOrCreate,FileAccess.ReadWrite);
StreamWriter _sn_writer = new StreamWriter(_sn);
StreamReader _sn_reader = new StreamReader(_sn);

если в проекте доступ к 1 и тому же файлу задавать двумя переменными и проект будет глобально знать об их существовании, то возникнет ошибка, что уже используется файл при попытке подключения записывающей переменной к файлу. Как я уже написал в дополнении к вопросу, проблема решается путем применения using (System.IO.StreamReader readfile = new System.IO.StreamReader(файл))
///
>
и
using (System.IO.StreamWriter readfile = new System.IO.StreamWriter(файл))
///
> Илья Булучев Гуру (3117) System.IO.StreamReader readfile = new System.IO.StreamReader(файл) readfile.Close(); System.IO.StreamWriter readfile2= new System.IO.StreamWriter(файл) readfile2.Close();

>>Явных проблем в архитектуре самой программы нет, над этим постарался.
У вас наглядная 100% ПРОБЛЕМА (именно капсом) в архитектуре, а теперь поясню
1) Если вы постоянно работаете с файлом - во первых отображайте его в память, это ускорит обработку и снимет часть нагрузки с винчестера, но это актуально больше для ssd, привыкайте сразу делать грамотно.
2) Если таки работа с файлом нужна из нескольких мест - заведите переменную для работы с этим файлом, и держите его открытым всегда, просто передавайте из класса в класс ссылку на него
3) Ну и наконец третье зачем вы открываете файл каждый раз заного для чтения\перезаписи\дозаписи - открывайте файл сразу со всеми нужными режимами. т. е. и на чтение и на запись и на создание (создание - на случай отсутствия искомого файла, если его отсутствие не должно вызывать ошибки)

зы.. а вообще работать с файлом не есть кароший тон, загрузите в память файл и работайте с его копией в памяти, я ведь верно понял что файлы сравнительно не большого размера?)

Спасибо за критику! Ее так не хватало.
Что вы имеете ввиду под выражением "капсом"?
1) я так понял однажды открыть файл и переместить все его данные в оперативную память в защищенную ячейку, закрывается только в случае закрытия программы или вызова определенной функции программой. Вносить изменения в эту ячейку и при окончательном сохранении записывать в файл и освобождать ячейку в оперативке. Как это сделать? Ума не приложу.
2) Пытался держать открытым, возникает исключение типа "файл уже используется" при попытке перезаписи данных.
3) Загружаю данные (текст, который потом по определенной закономерности преобразую в таблицу в программе и производится удобные манипуляции) из файла, в режиме онлайн я абстрактно меняю табличные значения, жму "сохранить" и файл, с которого я считывал данные, п Илья Знаток (251) перезаписывается с новыми значениями, при следующей подзагрузке этого же файла, данные значения уже будут отражены в файле, что мне необходимо. Таких файлов около 110 шт. Никакого лучшего решения я не придумал. Я знаю, что я очень много не знаю, я самоучка и стремлюсь впитывать полезную информацию. Можете что подсказать?

И так, раз такое дело, то тебе стоит поэксперементировать с методами:
Dispose()
Dispose(Boolean)
Finalize()
Close()

В начале компьютеры поддерживали только кодировку ASCII, но для поддержки символов на других языках (например, китайских символов) и некоторых специальных символов (например, €) был введен набор символов Unicode. Существует множество методов кодирования, основанных на наборе символов Unicode, таких как UTF-7, UTF-8, Unicode и UTF-32. В операционной системе Windows первые несколько байтов текстового файла используются для указания кодировки файла

Если вы используете NotePad или WordPad для открытия текстового файла, вам не нужно беспокоиться о кодировке файла, потому что эти приложения сначала прочитают первые несколько байтов файла, чтобы определить кодировку файла, а затем используют правильную кодировку. Показать каждый символ в тексте. На рисунке ниже вы можете увидеть, какие методы кодирования можно выбрать при сохранении документа в NotePad.


Читать текстовый файл

Если вы хотите прочитать Не много содержимого файла Вы можете использовать File.ReadAllText (filePath) или метод кодирования file.ReadAllText (FilePath, Encoding). Все они читают текст сразу и возвращают строку, содержащую весь текст

Also Может также использоваться File.ReadAllLines Этот метод читает все строки текстового содержимого одновременно и возвращает массив строк. Элементы массива являются содержимым каждой строки.

когда Содержание текста относительно велико Вместо того, чтобы читать текст сразу, мы должны Использование метода потока Читать содержание.

После завершения инициализации вы можете читать по одной строке за раз, вы также можете читать по одному символу за раз, вы также можете читать несколько символов за раз, или вы можете даже прочитать все сразу

После использования StreamReader не забудьте закрыть его: sR.Close ();

Если нам нужно читать построчно, читать весь текстовый файл, вот полный пример:

Написать в текстовый файл

Запись файлов такая же, как чтение файлов, если вы хотите Не так много написано Вы можете использовать File.WriteAllText Способ записать все в файл сразу. Если вы хотите записать содержимое строки в файл, вы можете использовать File.WriteAllText (FilePath) или указать метод кодирования File.WriteAllText (FilePath, Encoding) метод

Если у вас есть массив строк, вы хотите записать каждый элемент массива в виде строки в файл, вы можете использовать метод File.WriteAllLines

При использовании метода File.WriteAllText или File.WriteAllLines, если указанный путь к файлу не существует, будет создан новый файл, если файл уже существует, исходный файл будет перезаписан

Когда писать Больше контента При использовании того же Запись в потоковом режиме

После инициализации вы можете использовать объект StreamWriter для записи одной строки за раз, одного символа, одного символьного массива или даже части символьного массива

Читайте также: