在处理底层流后使用 StreamReader 吗?

发布于 2024-12-04 02:57:31 字数 680 浏览 1 评论 0原文

使用 StreamReader,如果您处理底层流,我认为您应该无法再读取。

这是真的表明 this 问题,如果底层流的生命周期在其他地方处理,则建议您不必处置 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

这怎么可能?

Using a StreamReader, if you dispose the underlying stream, I thought you shouldn't be able to read anymore.

That this is true suggests this question, where it's suggested that you don't have to dispose the StreamWriter (in their case) if the life of the underlying stream is handled elsewhere.

But that's not the case. What I did was the following:

I have a file called delme.txt containing the following

abc
def
ghi

The I run this:

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

    Console.WriteLine(sr.ReadLine());

    s.Dispose();

    Console.WriteLine(sr.ReadLine());

And the result is:

abc
def

How is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

呆萌少年 2024-12-11 02:57:31

您的 StreamReader 已将下一行读取到其缓冲区中。
在缓冲区中的数据耗尽之前,它不会返回到源 Stream

事实上,在这种情况下它不可能抛出异常,因为没有幂等方法来查明 Stream 是否已被释放。 (没有 IsDispose 属性)

Your StreamReader already read the next line into its buffer.
It won't go back to the source Stream until it runs out of data in its buffer.

In fact, it would be impossible for it to throw an exception in that case, since there is no idempotent way to find out whether a Stream has been disposed. (There is no IsDisposed property)

来世叙缘 2024-12-11 02:57:31

为了添加@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 行。

To add to @SLaks answer, here will demonstrate (using a file with a couple thousand lines of text):

        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();

It will print out lots and lots of lines, like a couple hundred, then will throw an Exception. My output ended like this:

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

In fact we see that there is a constructor for StreamReader that takes a parameter bufferSize as the fourth parameter:

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

Using 10000, it actually prints out a total of 1248 lines for me before crashing. Also, the smallest possible value you can use is 1, and for that case, it still pre-fetches 25 lines.

萤火眠眠 2024-12-11 02:57:31

这里你需要理解的是 dispose 正在尝试做什么。

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

它表示如果 TextReader 完成,则 TextReader 将处于不可用状态。也许,因为它还没有读完所有内容,所以它还没有被认为已经完成;因此,您可以继续使用它。这是我的猜测。

What you need to understand here is what dispose is trying to do.

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

It says the TextReader will be an unusable state if the TextReader is finished. Perhaps, since it hasn't read everything, it is not considered finished; therefore, you can continue to use it. That is my guess.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文