FileStream“无法访问关闭的文件" [英] FileStream "cannot access closed file"

查看:310
本文介绍了FileStream“无法访问关闭的文件"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么当我使用using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write))时会收到上述错误消息,但是当我将其替换为fileStream = File.Create(path);时,程序可以完美地执行吗?

Why am I receiving the above error message when I use using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write)) but the programme executes perfectly when I replace it with fileStream = File.Create(path); ?

我想将控制台输出附加到外部文件.这是我的代码:

I want to append the console output to an external file. Here's my code:

 //copy console output to file in bin\Debug folder
    class ConsoleCopy : IDisposable
    {
        FileStream fileStream;
        StreamWriter fileWriter;
        TextWriter doubleWriter;
        TextWriter oldOut;
        class DoubleWriter : TextWriter
        {
            TextWriter one;
            TextWriter two;
            public DoubleWriter(TextWriter one, TextWriter two)
            {
                this.one = one;
                this.two = two;
            }
            public override Encoding Encoding
            {
                get { return one.Encoding; }
            }
            //Clears all buffers for the current writer
            public override void Flush()
            {
                one.Flush();

                two.Flush();
            }
            public override void Write(char value)
            {
                **one.Write(value);**//error thrown here
                two.Write(value);
            }
        }
        public ConsoleCopy(string path)
        {
            oldOut = Console.Out;
            try
            {
                **//fileStream = File.Create(path);** //runs alright with this line
                fileWriter = new StreamWriter(fileStream);
                fileWriter.AutoFlush = true;
                doubleWriter = new DoubleWriter(fileWriter, oldOut);
            }
            catch (Exception e)
            {
                Console.WriteLine("Cannot open file for writing");
                Console.WriteLine(e.Message);
                return;
            }
            Console.SetOut(doubleWriter);
        }
        public void Dispose()
        {
            Console.SetOut(oldOut);
            if (fileWriter != null)
            {
                fileWriter.Flush();
                fileWriter.Close();
                fileWriter = null;
            }
            if (fileStream != null)
            {
                fileStream.Close();
                fileStream = null;
            }
        }
    }//end of consoleCopy

我这样在我的主要方法中调用此方法:

I call this method in my main method as such:

 //pass output to ConsoleCopy method for copying to .txt file
        using (var cc = new ConsoleCopy("mylogfile.txt"))
        {
           DateTime theDate = DateTime.UtcNow;

            string custom = theDate.ToString("d");

            Console.WriteLine("User has logged in on " + custom);
        }

更新:

该错误先前显示在one.Write(value)上.感谢彼得,我设法解决了这个问题.感谢大家的贡献和帮助:)

The error was previously shown at one.Write(value). I've managed to solve it though thanks to Peter. Thanks everyone for your contributions and help :)

推荐答案

如果在编写之前就得到了它,那是因为我读错了问题,并将using语句放在ConsoleCopy构造函数中意味着,当ConsoleCopy完成创建后,然后关闭FileStream.在您尝试对其进行写入时,因为它已被关闭,您会收到该异常.可以采用相同的解决方案-保留FileStream的打开状态,并在Dispose()中使用主方法中的using语句将其关闭.

If you're getting it before you write, then it's because I misread the question and putting the using statement in the ConsoleCopy constructor means that when the ConsoleCopy is finished being created, the FileStream is closed then. By the time you try to write to it, because it's already been closed you get that exception. The same solution would apply - leave the FileStream open and close it in Dispose() where it should be with the using statement in the main method.

如果我的理解正确,那么您就可以处理该例外,对吗?如果是这样,那是因为实际上发生的事情是您两次关闭该流.

If I understand correctly, you get that exception on disposal, right? If so, that's because what's happening is essentially that you're closing that stream twice.

using (var cc = new ConsoleCopy("mylogfile.txt"))
{
    // At this time, your filestream is created with the using statement.
    // Writing happens here.
    // Your filestream is closed at the end of the using statement inside of the ConsoleCopy constructor.
} 
// At this point, ConsoleCopy tries to call Dispose(), which flushes and closes everything again. However, this throws an exception because the using statement already closed the FileStream.

如果您的目标是附加到文件末尾,而Dispose()方法在内部关闭所有内容,为什么不替换

If your goal is to append to the end of the file and your Dispose() method closes everything internally, why not just replace

**//fileStream = File.Create(path);** //runs alright with this line

使用

fileStream = File.Open(path, System.IO.FileMode.Append, System.IO.FileAccess.Write);

并让您主体中的using语句为您内部关闭流吗?

and let the using statement in your main close the streams internally for you?

这篇关于FileStream“无法访问关闭的文件"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆