Использование StreamReader после удаления основного потока? - PullRequest
4 голосов
/ 12 сентября 2011

Используя StreamReader, если вы удалите базовый поток, я подумал, что вы больше не сможете читать.

То, что это правда, наводит на мысль этот вопрос, где предполагается, чтовам не нужно утилизировать StreamWriter (в их случае), если жизнь базового потока обрабатывается в другом месте.

Но это не так.Я сделал следующее:

У меня есть файл с именем delme.txt, содержащий следующее

abc
def
ghi

Я запускаю это:

    Stream s = File.OpenRead(@"C:\delme.txt");
    StreamReader sr = new StreamReader(s, Encoding.ASCII);

    Console.WriteLine(sr.ReadLine());

    s.Dispose();

    Console.WriteLine(sr.ReadLine());

И результатэто:

abc
def

Как это возможно?

Ответы [ 3 ]

10 голосов
/ 12 сентября 2011

Ваш StreamReader уже прочитал следующую строку в своем буфере.
Он не вернется к источнику Stream, пока не закончатся данные в его буфере.

Фактически,в этом случае было бы невозможно выбросить исключение, поскольку не существует идемпотентного способа выяснить, был ли уничтожен Stream.(Нет IsDisposed собственности)

5 голосов
/ 12 сентября 2011

Чтобы добавить к ответу @SLaks, здесь будет продемонстрировано (с использованием файла с парой тысяч строк текста):

        Stream s = File.OpenRead(path);
        StreamReader sr = new StreamReader(s, Encoding.ASCII);

        Console.WriteLine(sr.ReadLine());

        s.Dispose();

        int i = 1;
        try
        {
            while (!sr.EndOfStream)
            {
                Console.WriteLine(sr.ReadLine());
                i++;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

        Console.WriteLine(i + " lines total");

        Console.ReadLine();

Он выведет множество строк, как пара сотен,тогда скинет исключение.Мой вывод закончился так:

qrs
tuv
wxy
zab
cde
fgh
ijk
lmn
Cannot access a closed file.
204 lines total

На самом деле мы видим, что существует конструктор для StreamReader, который принимает параметр bufferSize в качестве четвертого параметра:

StreamReader sr = new StreamReader(s, Encoding.ASCII, false, 10000);

Использование10000, он на самом деле выводит мне 1248 строк перед тем, как рухнуть.Кроме того, наименьшее возможное значение, которое вы можете использовать, равно 1, и для этого случая оно по-прежнему предварительно выбирает 25 строк.

0 голосов
/ 12 сентября 2011

Что вам нужно понять, это то, что пытается сделать распоряжение.

http://msdn.microsoft.com/en-us/library/ms227563.aspx

В нем говорится, что TextReader будет неиспользуемым состоянием, если TextReader будет завершен. Возможно, поскольку он не прочитал все, он не считается завершенным; следовательно, вы можете продолжать использовать его. Это мое предположение.

...