Можете ли вы удержать StreamReader от удаления основного потока? - PullRequest
46 голосов
/ 07 декабря 2009

Есть ли способ сделать это:

this.logFile = File.Open("what_r_u_doing.log", FileMode.OpenOrCreate, FileAccess.ReadWrite);

using(var sr = new StreamReader(this.logFile))
{
    // Read the data in
}

// ... later on in the class ...

this.logFile = File.Open("what_r_u_doing.log", FileMode.OpenOrCreate, FileAccess.ReadWrite);

using(var sw = new StreamWriter(this.logFile))
{
    // Write additional data out...
}

Без необходимости открывать файл дважды?

Я не могу заставить StreamReader не удалять мой поток. Я не хочу просто выпустить это из области видимости. Тогда сборщик мусора в конце концов вызовет Dispose, уничтожив поток.

Ответы [ 8 ]

67 голосов
/ 04 ноября 2011

.NET 4.5, наконец, исправит эту проблему с помощью новых конструкторов StreamReader и StreamWriter, которые принимают параметр leftOpen:

StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)

StreamWriter(Stream stream, System.Text.Encoding encoding, int bufferSize, bool leaveOpen)
46 голосов
/ 07 декабря 2009

Я тоже не хочу просто выходить за рамки. Тогда сборщик мусора в конце концов вызовет Dispose, уничтожив поток.

Сборщик мусора вызовет метод Finalize (деструктор), а не метод Dispose. Финализатор вызовет Dispose(false), который не удалит базовый поток. Вы должны быть в порядке, оставив StreamReader выйти из области видимости, если вам нужно напрямую использовать базовый поток. Просто убедитесь, что вы удаляете базовый поток вручную, когда это уместно.

16 голосов
/ 07 декабря 2009

Вы можете использовать класс NonClosingStreamWrapper из библиотеки MiscUtil Джона Скита , он служит именно для этой цели

3 голосов
/ 07 декабря 2009

Вы можете создать новый класс, который наследуется от StreamReader, и переопределить метод Close; внутри вашего метода Close вызов Dispose (false), который, как указал Мерада, не закрывает поток. То же самое относится и к StreamWriter, конечно.

Однако, похоже, что лучшим решением было бы просто удерживать экземпляры StreamReader и StreamWriter до тех пор, пока они вам могут понадобиться. Если вы уже планируете держать поток открытым, вы также можете оставить StreamReader и StreamWriter открытыми. Если вы правильно используете StreamWriter.Flush и Stream.Seek, вы сможете выполнить эту работу даже при чтении и письме.

2 голосов
/ 10 апреля 2014

Используйте другую перегрузку конструктора, где вы можете указать для параметра «leftOpen» значение «true»

2 голосов
/ 07 декабря 2009

Просто удалите блок использования. Вам не нужно Dispose () StreamReader, если вы не хотите делать Dispose () поток, я думаю.

0 голосов
/ 24 января 2018

Я всегда использую что-то вроде этого: (также используется аргумент leaveOpen)

public static class StreamreaderExtensions
{
    public static StreamReader WrapInNonClosingStreamReader(this Stream file) => new StreamReader(file, Encoding.UTF8, true, 1024, true);
}

Использование:

using (var reader = file.WrapInNonClosingStreamReader())
{
     ....
}
0 голосов
/ 07 декабря 2009

Закройте его в предложении try / finally, когда закончите.

var sr = new StreamReader();
try {
    //...code that uses sr
    //....etc
}
finally
{
    sr.Close();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...