如何使用C#同时读/写表格文件?

我创建了多个服务器。每个服务器都必须将一些数据发送到自己的客户端。 我正在使用TCP / IP协议。 为防止因客户端断开连接而导致数据丢失,我使用文本文件作为缓冲区。 所以在程序中,每个服务器都有一个线程,它继续检查客户端是否连接。 如果它已连接,则它从缓冲区读取并将其发送到客户端。 每当必须将一些新数据发送到客户端时,我首先检查客户端是否已连接。如果客户端未连接,则我将数据写入相同的缓冲区文本文件。 我面临的问题是,当线程从中读取文件时,我无法写入文件。

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace WindowsFormsApplication1 { public class TcpIp { public int machinePort; public static int port1 = 1024; public static int count = 0; public string bufferName; FileStream buffer; Socket client; public IPAddress localIp; public TcpListener sender; StreamReader reader ; FileStream iStream; //this.get public TcpIp(string id) { this.machinePort = port1 + count; while (!isAvailable(this.machinePort)) { count++; this.machinePort = port1 + count; } this.bufferName = WindowsFormsApplication1.Program.path + "machine_" + id + ".txt"; buffer = new FileStream(this.bufferName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); localIp = IPAddress.Parse(WindowsFormsApplication1.Program.ip); sender = new TcpListener(localIp, this.machinePort); // this.oStream = new FileStream(this.bufferName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); //this.iStream = new FileStream(this.bufferName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); // reader = new StreamReader(this.iStream); } bool isAvailable(int port) { bool isAvailable = true; IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties(); TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections(); foreach (TcpConnectionInformation tcpi in tcpConnInfoArray) { if (tcpi.LocalEndPoint.Port == port) { isAvailable = false; break; } } return isAvailable; } public void createServer() { this.sender.Start(); string line; reader = new StreamReader(buffer); //client = sender.AcceptSocket(); while (true) { line = reader.ReadLine(); if (!connected()) { client = sender.AcceptSocket(); } while (reader.EndOfStream && line != null) { byte[] bytes = System.Text.Encoding.UTF8.GetBytes(line); client.Send(bytes, 0, bytes.Length, SocketFlags.None); line = reader.ReadLine(); } // iStream.Flush(); Thread.Sleep(3000); //reader = new StreamReader(iStream); } } public void writeToClient(string data) { if (connected()) { //send data to client byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data); //System.Buffer.BlockCopy(data.ToCharArray(), 0, bytes, 0, bytes.Length); this.client.Send(bytes, 0, bytes.Length, SocketFlags.None); } else { //write to file while (true) { try { StreamWriter sw = File.AppendText(this.bufferName); sw.WriteLine(data); sw.Close(); break; } catch (Exception ex) { Console.WriteLine("WaitForFile {0} failed to get an exclusive lock: "+ex.Message ); // Wait for the lock to be released System.Threading.Thread.Sleep(500); } } } } bool connected() { if (client == null) return false; else return client.Connected; } } } 

任何启示都将不胜感激。 谢谢 :)

实际问题是您混淆了对文件的访问权限。

您可以通过buffer = new FileStream(this.bufferName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);打开流buffer = new FileStream(this.bufferName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); 为了从打开的流创建StreamReader以便以后读取读取reader = new StreamReader(buffer);

OTOH,你想通过StreamWriter sw = File.AppendText(this.bufferName);获得一个StreamWriter来写入文件StreamWriter sw = File.AppendText(this.bufferName); 。 这会尝试再次打开文件,因为文件共享模式不匹配而失败。

因此,您需要通过完全相同的“句柄”(此处为FileStream)来访问该文件以进行写入和读取。 此外,不要忘记通过某种锁定机制序列化访问,以使其成为线程安全的。 否则,您将收到损坏的数据。 您可能需要维护读/写指针(Stream.Position)。

您无法同时从同一文本文件中读取和写入。

如果你真的想使用文本文件,为什么不使用其中的两个:一个读取,一个读写。 一旦读取文件为空 – >读取文件是新的写入文件,反之亦然。

这听起来很逻辑,因为文件正在使用中,2个线程不可能同时访问文件。

想象一下,即使有可能,你也会有一些非常奇怪的行为。

为什么不使用lock()来确保在给定时间只有一个线程可以访问该文件?

使用异步编程,您无需等到锁定释放后再继续执行程序。

你必须创建这样的线程

 Thread thread = new Thread(yourMethod()); 

当你有多个线程时,你需要的是ReaderWriterLockSlim。 这是链接 。

它允许您通过多个线程读取文件,但使用一个Thread写入文件。 我想这会解决你的问题。