使用C#中的autoresetevent读取和写入文件

本文关键字:文件 读取 中的 autoresetevent 使用 | 更新日期: 2023-09-27 18:29:55

我已经编写了一个简单的线程同步程序。但是当我运行这个程序时,我得到一个错误"进程无法访问文件D:''Vivek.txt,因为它正被另一个进程使用。"为什么我得到这个错误。

class Program
{
    const string Filepath = "D:''Vivek.txt";
    static AutoResetEvent writerwaithandle= new AutoResetEvent(true);// Signaled state
    static AutoResetEvent readerwaithandle = new AutoResetEvent(false);
    static void Main()
    {
        if (File.Exists(Filepath))
        {
            File.Delete(Filepath);                                          
        }
        File.CreateText(Filepath);
        CreateWriterThread();
        CreateReaderThread();
        Console.ReadKey();
    }
    private static void CreateWriterThread()
    {
        for (int i = 1; i <= 10;i++ )
        {
            var thread = new Thread(WriteFile);
            thread.Name = "Writer " + i;
            thread.Start();
            Thread.Sleep(250);
        }
    }
    private static void CreateReaderThread()
    {
        for (int i = 1; i <= 10; i++)
        {
            var thread = new Thread(ReadFile);
            thread.Name = "Reader " + i;
            thread.Start();
        }
    }
    private static void WriteFile()
    {
        writerwaithandle.WaitOne();
        var stream = new FileStream(Filepath, FileMode.Append);
        var streamwriter = new StreamWriter(stream);
        streamwriter.WriteLine("written by"+Thread.CurrentThread.Name+DateTime.Now));
        streamwriter.Flush();
        streamwriter.Close();
        readerwaithandle.Set();
    }
    private static void ReadFile()
    {
        readerwaithandle.WaitOne();
        if (File.Exists(Filepath))
        {
            var stream = new FileStream(Filepath, FileMode.Open);
            var streamreader = new StreamReader(stream);
            var text = streamreader.ReadToEnd();
            streamreader.Close();
            Console.WriteLine("Read by thread {0} 'n",Thread.CurrentThread.Name);
            Console.WriteLine(text);
        }
        writerwaithandle.Set();
    }
}

当我替换的代码时

if (File.Exists(Filepath))
{
  File.Delete(Filepath);                                          
}
  File.CreateText(Filepath);

if (!File.Exists(Filepath))
{
  File.CreateText(Filepath);
}

该程序首次显示相同的错误。从那以后,它再也不会出现任何错误。请任何人告诉我错误的区域,原因和什么应该是最好的解决方案。

使用C#中的autoresetevent读取和写入文件

当您使用FileStream时,请像一样将其与using一起使用

using (var fileStream = new FileStream(Filepath, FileMode.Open))
{
   Your code...
}

这样可以确保流得到正确的处理。

您也可以将StreamReaderusing 一起使用

using (var fileStream = new FileStream(Filepath, FileMode.Open))
{
    using (var reader = new StreamReader(stream))
    {
        Your code...
    }
}

提高警惕,查看File.CreateText 的文档

创建或打开用于编写UTF-8编码文本的文件。

返回值类型:System.IO.StreamWriter写入的StreamWriter

使用UTF-8编码到指定的文件

这意味着不需要创建新的FileStream,因为FileStream已经创建并在使用File.CreateText时返回。您应该只在代码中使用创建的FileStream。

这是你的代码的固定版本:

 class Program
    {
        const string Filepath = "D:''Vivek.txt";
        static AutoResetEvent writerwaithandle = new AutoResetEvent(true);// Signaled state
        static AutoResetEvent readerwaithandle = new AutoResetEvent(false);
        static void Main()
        {
            if (File.Exists(Filepath))
            {
                File.Delete(Filepath);
            }
            //File.CreateText(Filepath);
            CreateWriterThread();
            CreateReaderThread();
            Console.ReadKey();
        }
        private static void CreateWriterThread()
        {
            for (int i = 1; i <= 10; i++)
            {
                var thread = new Thread(WriteFile);
                thread.Name = "Writer " + i;
                thread.Start();
                Thread.Sleep(250);
            }
        }
        private static void CreateReaderThread()
        {
            for (int i = 1; i <= 10; i++)
            {
                var thread = new Thread(ReadFile);
                thread.Name = "Reader " + i;
                thread.Start();
            }
        }
        private static void WriteFile()
        {
            writerwaithandle.WaitOne();

            var streamwriter = File.CreateText(Filepath);
            //var stream = new FileStream(Filepath, FileMode.Append);
            //var streamwriter = new StreamWriter(stream);
            streamwriter.WriteLine("written by" + Thread.CurrentThread.Name + DateTime.Now);
            streamwriter.Flush();
            streamwriter.Close();
            readerwaithandle.Set();
        }
        private static void ReadFile()
        {
            readerwaithandle.WaitOne();
            if (File.Exists(Filepath))
            {
                var stream = new FileStream(Filepath, FileMode.Open);
                var streamreader = new StreamReader(stream);
                var text = streamreader.ReadToEnd();
                streamreader.Close();
                Console.WriteLine("Read by thread {0} 'n", Thread.CurrentThread.Name);
                Console.WriteLine(text);
            }
            writerwaithandle.Set();
        }
    }