Чтение и запись файла с помощью autoresetevent в C#
Я написал простую программу синхронизации потоков. Но когда я запускаю эту программу, я получаю сообщение об ошибке: "Процесс не может получить доступ к файлу" 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);
}
программа показывает ту же ошибку в первый раз. после этого это никогда не дает никакой ошибки. Пожалуйста, кто-нибудь, скажите мне область ошибки, причину и какое должно быть лучшее решение.
2 ответа
Когда вы используете FileStream
всегда используйте его с using
лайк
using (var fileStream = new FileStream(Filepath, FileMode.Open))
{
Your code...
}
Это гарантирует, что поток будет расположен правильно.
Вы также можете использовать StreamReader
вместе с using
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();
}
}