我如何能同时读/写使用C#形成一个文本文件? [英] How can I simultaneously read/write form a text file using C#?

查看:108
本文介绍了我如何能同时读/写使用C#形成一个文本文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有多个服务器created.Each人有一些数据发送到它自己的客户。我使用的TCP / IP协议。为了防止因客户端的任何数据丢失松脱,我使用一个文本文件作为缓冲。所以在节目中,存在对不断如果客户端被连接或不检查每个服务器线程。如果它被连接,然后它从缓冲器读取并把它发送到客户端。每当一些新的数据必须被发送到客户端,我首先检查是否客户是connected.If客户端未连接然后我写数据到相同的缓冲液文本文件。 。我现在面临的问题是,我无法同时线程从中读取写入到文件

I have multiple servers created.Each one has to send some data to its own client. I am using TCP/IP protocol. To prevent any data loss due to client getting disconnected, I am using a text file as a buffer. So in the program , there is a thread for each server which keeps on checking if the client is connected or not. If it is connected then it reads from the buffer and sends it to client. whenever some new data has to be send to client , I am first checking if client is connected.If client isn't connected then I am writing data to the same buffer text file. The problem I am facing is that I am unable to write to the file while thread is reading from it.

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;
        }
    }
}



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

Any enlightenment would be appreciated. Thank you :)

推荐答案

实际的问题是,你混淆了对文件的访问

The actual problem is that you mix up access to the file.

您打开由缓冲液=新的FileStream(this.bufferName,FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.ReadWrite)流;为了来创建一个的StreamReader 读者=新的StreamReader(缓冲)供日后阅读打开的流;

You open a stream by buffer = new FileStream(this.bufferName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); in order to create a StreamReader from the opened stream for later reading by reader = new StreamReader(buffer);.

OTOH,你希望得到一个的StreamWriter 的StreamWriter写入文件SW = File.AppendText( this.bufferName); 。这将尝试再次打开该文件,它会失败,因为不匹配的文件共享模式。

OTOH, you want get a StreamWriter for writing to the file by StreamWriter sw = File.AppendText(this.bufferName);. This tries to open the file again which fails because of mismatching file sharing mode.

所以,你需要通过同样的处理访问该文件的写入和读取(这里的FileStream)。另外,不要忘记一些锁定机制,以使它线程安全的连载访问。否则,你会得到损坏的数据。你可能需要维持读/写指针(Stream.Position)。

So you need to access the file for writing and reading via the very same "handle" (here FileStream). Furthermore, don't forget to serialize access by some locking mechanism in order to make it thread-safe. Otherwise, you'll get corrupted data. You'll probably need to maintain the read/write pointer (Stream.Position).

这篇关于我如何能同时读/写使用C#形成一个文本文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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