【问题标题】:Trying to REopen Sytem.IO Objects尝试重新打开 Sytem.IO 对象
【发布时间】:2015-10-29 15:51:49
【问题描述】:

我正在制作一个程序,允许您掷五种不同类型的多面“骰子”,当您掷出一个数字时,我希望它把它存储在一个文本文件中。在我的表单顶部有一个菜单条项目,您可以单击它,它会关闭 StreamWriter 和 FileStream 并打开第二个表单,显示滚动的数字以及滚动的骰子(我只知道滚动的数字现在为简单起见),它显示得很好。但是当我关闭 Reader、Stream 和第二个表单并返回到第一个表单时,我尝试重新打开 Writer 和 Stream,它告诉我已经在使用中。

我的第一个表单的代码:

using System;
using System.Windows.Forms;
using System.IO;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private Random ran = new Random();
        static FileStream outFile = new FileStream(@"H:\C#\Independant Projects\VirtualDice\History.txt", FileMode.OpenOrCreate, FileAccess.Write);
        StreamWriter writer = new StreamWriter(outFile);

        private int ranNum;

        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            ranNum = ran.Next(1, 21);
            Display();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ranNum = ran.Next(1, 13);
            Display();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            ranNum = ran.Next(1, 5);
            Display();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            ranNum = ran.Next(1, 9);
            Display();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            ranNum = ran.Next(1, 11);
            Display();
        }
        private void Display()
        {
            lblNum.Text = String.Format("{0}", ranNum);
            lblNum.Visible = true;
            writer.WriteLine(ranNum);
        }

        private void historyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedIndex = 1;
            writer.Close();
            outFile.Close();
            History history = new History();
            history.ShowDialog();
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            FileStream outFile = new FileStream(@"H:\C#\Independant Projects\VirtualDice\History.txt", FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter writer = new StreamWriter(outFile);
            tabControl1.SelectedIndex = 0;
        }
    }
}

我的第二个表单的代码:

using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class History : Form
    {
        public History()
        {
            InitializeComponent();
        }

        static private FileStream inFile = new FileStream(@"H:\C#\Independant Projects\VirtualDice\History.txt", FileMode.Open, FileAccess.Read);
        private StreamReader reader = new StreamReader(inFile);

        private void History_Load(object sender, EventArgs e)
        {
            string item;

            item = reader.ReadLine();
            try
            {
                lstHistory.Items.Add(item);
            }
            catch (Exception)
            {
                lstHistory.Font = new Font(lstHistory.Font.Name, 12, lstHistory.Font.Unit);
                lstHistory.Items.Add("You have not rolled any numbers");
            }
        }
    }
}

【问题讨论】:

    标签: c# streamreader streamwriter system.io.file


    【解决方案1】:

    一旦完成,您需要正确释放非托管资源(在您的情况下是文件)。完成后调用stream 上的Dispose() 函数:

    if(inFile != null){
        inFile.Dispose();
    }
    

    更好的是,将其包装在 using() 中,如下所示:

    using(FileStream outFile = new FileStream(@"H:\C#\Independant Projects\VirtualDice\History.txt", FileMode.OpenOrCreate, FileAccess.Write)){
        StreamWriter writer = new StreamWriter(outFile);
        tabControl1.SelectedIndex = 0;
    }
    

    using 将在正确的时间以正确的方式自动为您调用Dispose()(即,它会在调用Dispose() 之前首先检查对象是否为null,以避免出现“空异常”)。检查this link for more details about the using statement

    但是,如果您在很多地方都有相同的代码,那么将其包装在 singleton 模式中可能是值得的。检查this Microsoft article on how to write a singleton pattern in C#

    【讨论】:

    • 是否有需要使用 using 语句,因为我找不到单例关键字?其他两个解决方案也对我不起作用。
    • 其他两种对您不起作用的解决方案是什么?单例是一种模式而不是一种语言语法。这就像将打开、读取和写入文件的所有功能放在一个类中,并在代码中的任何地方调用它的函数。检查我提供的链接以了解如何实现和使用该模式。至于using,是的,它是C# 中的一个语句,您可以阅读更多关于它的信息here
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多