Почему я должен закрыть() файл в C#?
Я знаю, это может показаться глупым, но почему следующий код работает только если я рядом() файла? Если я не закрою файл, весь поток не будет записан.
действия:
- запустить этот код при загрузке формы.
- закрыть форму с помощью мыши, как только он появится.
- программа завершается.
не должен ли объект file быть сброшен или закрыт автоматически, когда он выходит за рамки? Я новичок в C#, но я привык добавлять вызовы Close () в деструкторах C++.
// Notes: complete output is about 87KB. Without Close(), it's missing about 2KB at the end.
// Convert to png and then convert that into a base64 encoded string.
string b64img = ImageToBase64(img, ImageFormat.Png);
// Save the base64 image to a text file for more testing and external validation.
StreamWriter outfile = new StreamWriter("../../file.txt");
outfile.Write(b64img);
// If we don't close the file, windows will not write it all to disk. No idea why
// that would be.
outfile.Close();
6 ответов
C# не имеет автоматической детерминированной очистки. Вы должны обязательно вызвать функцию очистки, Если хотите управлять ее запуском. The using
блок является самым распространенным способом сделать это.
если вы не поместите в вызов очистки самостоятельно, то очистка произойдет, когда сборщик мусора решит, что память необходима для чего-то еще, что может быть очень долгое время спустя.
using (StreamWriter outfile = new StreamWriter("../../file.txt")) {
outfile.Write(b64img);
} // everything is ok, the using block calls Dispose which closes the file
EDIT: как указывает Харви, в то время как очистка будет предпринята когда объект собирается, это не является гарантией успеха. Чтобы избежать проблем с циклическими ссылками, среда выполнения не пытается завершить объекты в" правильном " порядке, поэтому FileStream
на самом деле уже может быть мертв к тому времени StreamWriter
finalizer запускается и пытается сбросить буферизованный вывод.
если вы имеете дело с объектами, которые нуждаются в очистке, сделайте это явно, либо с using
(для использования в локальной области) или путем вызова IDisposable.Dispose
(для долгоживущих объектов, таких как референты из член класса.)
потоки-это объекты, которые "управляют" или "обрабатывают" ресурсы, собранные без мусора. Поэтому они (потоки) реализуют интерфейс IDisposable, который при использовании с "использованием" гарантирует, что ресурсы, собранные без мусора, будут очищены. попробуйте это:
using ( StreamWriter outfile = new StreamWriter("../../file.txt") )
{
outfile.Write(b64img);
}
без #Close вы не можете быть уверены, когда базовый дескриптор файла будет правильно закрыт. Иногда это может быть при выключении приложения.
потому что вы используете streamwriter, и он не очищает буфер, пока вы Close()
писатель. Вы можете указать, что вы хотите, чтобы писатель смывал каждый раз, когда вы вызываете запись, установив AutoFlush
свойство streamwriter для true.
проверить документы. http://msdn.microsoft.com/en-us/library/system.io.streamwriter.aspx
Если вы хотите записать в файл без "закрытия", я бы использовал:
System.IO.File
кэш операционной системы запись в блок устройств, чтобы позволить ОС иметь лучшую производительность. Вы заставляете запись путем промывки буфера после записи установки streamwriter для автозапуска.
потому что дизайнеры C# клонировали Java, а не c++, несмотря на имя.
по-моему, они действительно пропустили лодку. Разрушение стиля C++ при выходе из области было бы намного лучше.
ему даже не нужно было бы освобождать память, чтобы быть лучше, просто автоматически запускать финализатор или метод IDisposable.