Exception, named pipe + serialization - c#

In the below example, NamedPipeServer is started or registered with name “File Transfer”.
The NamedPipeServer reads the content of a source file and creates an instance for “TransferFile” class setting the attributes such as source file name and file content (stream).
Server then serializes the "TransferFile" object and writes to the stream.
NamedPipeClient connects to the NamedPipeServer based whose server name is “File Transfer”.
and reads the stream. After reading the stream, Client deserializes to get the “TransferFile” object.
from the “FileTransfer” object, client creates the target file in specific directory with name from “FileName” attribute and content(byte[]) from “FileContent”.
Exception, when i use formatter.Deserialize(pipeClient).
TransferFile.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace FileTransfer
{
//file transfer class (serializable)
[Serializable]
public class TransferFile
{
public string FileName;
public Stream FileContent;
}
}
Named Pipe Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Runtime.Serialization;
using FileTransfer;
namespace ServerNamedPipe
{
class Program
{
static void Main()
{
//creating object for file transfer
using (NamedPipeServerStream pipeServer =
new NamedPipeServerStream("File Transfer", PipeDirection.Out))
{
Console.WriteLine("File Transfer Named Pipe Stream is ready...");
Console.Write("Waiting for client connection...");//waiting for any client connections
pipeServer.WaitForConnection();
Console.WriteLine("Client connected.");
try
{
string strFile = #"c:\Test\1\Srinivas.txt";
//creating FileTransfer Object ans setting the file name
TransferFile objTransferFile = new TransferFile() { FileName = new FileInfo(strFile).Name };
objTransferFile.FileContent = new MemoryStream();
//opening the source file to read bytes
using (FileStream fs = File.Open(strFile, FileMode.Open, FileAccess.Read))
{
byte[] byteBuffer = new byte[1024];
int numBytes = fs.Read(byteBuffer, 0, 1024);
//writing the bytes to file transfer content stream
objTransferFile.FileContent.Write(byteBuffer, 0, 1024);
//below code is to write the bytes directly to the pipe stream
//pipeServer.Write(byteBuffer, 0, 1024);
//Reading each Kbyte and writing to the file content
while (numBytes > 0)
{
numBytes = fs.Read(byteBuffer, 0, numBytes);
objTransferFile.FileContent.Write(byteBuffer, 0, 1024);
//below code is to write the bytes to pipe stream directly
//pipeServer.Write(byteBuffer, 0, numBytes);
}
//setting the file content (stream) position to begining
objTransferFile.FileContent.Seek(0, SeekOrigin.Begin);
//serializing the file transfer object to a stream
IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
try
{
//serialzing and writing to pipe stream
formatter.Serialize(pipeServer, objTransferFile);
}
catch (Exception exp)
{
throw exp;
}
}
}
// Catch the IOException that is raised if the pipe is
// broken or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
}
}
}
}
Named Pipe Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Pipes;
using System.Runtime.Serialization;
namespace ClientNamedPipe
{
class Program
{
static void Main(string[] args)
{
//connecting to the known pipe stream server which runs in localhost
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", "File Transfer", PipeDirection.In))
{
// Connect to the pipe or wait until the pipe is available.
Console.Write("Attempting to connect to File Transfer pipe...");
//time out can also be specified
pipeClient.Connect();
Console.WriteLine("Connected to File Transfer pipe.");
IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
//deserializing the pipe stream recieved from server
FileTransfer.TransferFile objTransferFile = (FileTransfer.TransferFile)formatter.Deserialize(pipeClient);
//creating the target file with name same as specified in source which comes using
//file transfer object
byte[] byteBuffer = new byte[1024];
using (FileStream fs = new FileStream(#"c:\Test\2\" + objTransferFile.FileName, FileMode.Create, FileAccess.Write))
{
//writing each Kbyte to the target file
int numBytes = objTransferFile.FileContent.Read(byteBuffer, 0, 1024);
fs.Write(byteBuffer, 0, 1024);
while (numBytes > 0)
{
numBytes = objTransferFile.FileContent.Read(byteBuffer, 0, numBytes);
fs.Write(byteBuffer, 0, numBytes);
}
}
Console.WriteLine("File, Received from server: {0}", objTransferFile.FileName);
}
Console.Write("Press Enter to continue...");
Console.ReadLine();
}
}
}

You don't say what exception you got, specifically. But just looking at the code, the most obvious problem is that you have a Stream field in your TransferFile object. You can't serialize a Stream object.
One option would be to use a byte[] object instead in the TransferFile class. You can initialize it from your file using File.ReadAllBytes().
Note that serializing the whole file is not very efficient. If you want to make the best use of your pipe bandwidth, you should skip the whole serialization-based scheme, and instead use BinaryWriter.Write(string) to send the file name, and then just write the actual contents of the file to the stream.
For example:
Server:
static void Main()
{
//creating object for file transfer
using (NamedPipeServerStream pipeServer =
new NamedPipeServerStream("File Transfer", PipeDirection.Out))
{
Console.WriteLine("File Transfer Named Pipe Stream is ready...");
Console.Write("Waiting for client connection...");//waiting for any client connections
pipeServer.WaitForConnection();
Console.WriteLine("Client connected.");
try
{
string strFile = #"c:\Test\1\Srinivas.txt";
using (BinaryWriter writer = new BinaryWriter(pipeServer, Encoding.UTF8, true))
{
writer.Write(strFile);
}
//opening the source file to read bytes
using (FileStream fs = File.Open(strFile, FileMode.Open, FileAccess.Read))
{
fs.CopyTo(pipeServer);
}
}
// Catch the IOException that is raised if the pipe is
// broken or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
}
}
Client:
static void Main(string[] args)
{
//connecting to the known pipe stream server which runs in localhost
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", "File Transfer", PipeDirection.In))
{
// Connect to the pipe or wait until the pipe is available.
Console.Write("Attempting to connect to File Transfer pipe...");
//time out can also be specified
pipeClient.Connect();
Console.WriteLine("Connected to File Transfer pipe.");
using (BinaryReader reader = new BinaryReader(pipeClient, Encoding.UTF8, true))
{
string fileName = reader.ReadString();
}
//creating the target file with name same as specified in source which comes using
//file transfer object
using (FileStream fs = new FileStream(#"c:\Test\2\" + fileName, FileMode.Create, FileAccess.Write))
{
pipeClient.CopyTo(fs);
}
Console.WriteLine("File, Received from server: {0}", fileName);
}
Console.Write("Press Enter to continue...");
Console.ReadLine();
}

Related

Can we unzip file in FTP server using C#

Can I extract the ZIP file in FTP and place this extracted file on the same location using C#?
It's not possible.
There's no API in the FTP protocol to un-ZIP a file on a server.
Though, it's not uncommon that one, in addition to an FTP access, have also an SSH access. If that's the case, you can connect with the SSH and execute the unzip shell command (or similar) on the server to decompress the files.
See C# send a simple SSH command.
If you need, you can then download the extracted files using the FTP protocol (Though if you have the SSH access, you will also have an SFTP access. Then, use the SFTP instead of the FTP.).
Some (very few) FTP servers offer an API to execute an arbitrary shell (or other) commands using the SITE EXEC command (or similar). But that's really very rare. You can use this API the same way as the SSH above.
If you want to download and unzip the file locally, you can do it in-memory, without storing the ZIP file to physical (temporary) file. For an example, see How to import data from a ZIP file stored on FTP server to database in C#.
Download via FTP to MemoryStream, then you can unzip, example shows how to get stream, just change to MemoryStream and unzip. Example doesn't use MemoryStream but if you are familiar with streams it should be trivial to modify these two examples to work for you.
example from: https://learn.microsoft.com/en-us/dotnet/framework/network-programming/how-to-download-files-with-ftp
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
request.Method = WebRequestMethods.Ftp.DownloadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine("Download Complete, status {0}", response.StatusDescription);
reader.Close();
response.Close();
}
}
}
decompress stream, example from: https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-compress-and-extract-files
using System;
using System.IO;
using System.IO.Compression;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
using (FileStream zipToOpen = new FileStream(#"c:\users\exampleuser\release.zip", FileMode.Open))
{
using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
{
ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt");
using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
{
writer.WriteLine("Information about this package.");
writer.WriteLine("========================");
}
}
}
}
}
}
here is a working example of downloading zip file from ftp, decompressing that zip file and then uploading the compressed files back to the same ftp directory
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string location = #"ftp://localhost";
byte[] buffer = null;
using (MemoryStream ms = new MemoryStream())
{
FtpWebRequest fwrDownload = (FtpWebRequest)WebRequest.Create($"{location}/test.zip");
fwrDownload.Method = WebRequestMethods.Ftp.DownloadFile;
fwrDownload.Credentials = new NetworkCredential("anonymous", "janeDoe#contoso.com");
using (FtpWebResponse response = (FtpWebResponse)fwrDownload.GetResponse())
using (Stream stream = response.GetResponseStream())
{
//zipped data stream
//https://stackoverflow.com/a/4924357
byte[] buf = new byte[1024];
int byteCount;
do
{
byteCount = stream.Read(buf, 0, buf.Length);
ms.Write(buf, 0, byteCount);
} while (byteCount > 0);
//ms.Seek(0, SeekOrigin.Begin);
buffer = ms.ToArray();
}
}
//include System.IO.Compression AND System.IO.Compression.FileSystem assemblies
using (MemoryStream ms = new MemoryStream(buffer))
using (ZipArchive archive = new ZipArchive(ms, ZipArchiveMode.Update))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
FtpWebRequest fwrUpload = (FtpWebRequest)WebRequest.Create($"{location}/{entry.FullName}");
fwrUpload.Method = WebRequestMethods.Ftp.UploadFile;
fwrUpload.Credentials = new NetworkCredential("anonymous", "janeDoe#contoso.com");
byte[] fileContents = null;
using (StreamReader sr = new StreamReader(entry.Open()))
{
fileContents = Encoding.UTF8.GetBytes(sr.ReadToEnd());
}
if (fileContents != null)
{
fwrUpload.ContentLength = fileContents.Length;
try
{
using (Stream requestStream = fwrUpload.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
}
catch(WebException e)
{
string status = ((FtpWebResponse)e.Response).StatusDescription;
}
}
}
}
}
}
}
If you're trying to unzip the files in place after they have been ftp uploaded, you will need to run a server side script with proper permissions that can be fired from within your c# application, or c# ssh as already described earlier.

C# server and client communication - send/receive data

I need to help, I want to make server and client, who will communicate together.(send/receive data)
Example: client sends username and password to server when I login and server checks it and sends (correct or not correct) to client.
Server and client can send and receive data, and more data together (for example: username, password ... in one communication)
I need from you the best example of communicating with the client, server, currently I have this script by youtube: enter link description here
There is send / receive method from youtube:
public class PacketWriter : BinaryWriter
{
// This will hold our packet bytes.
private MemoryStream _ms;
// We will use this to serialize (Not in this tutorial)
private BinaryFormatter _bf;
public PacketWriter() : base()
{
// Initialize our variables
_ms = new MemoryStream();
_bf = new BinaryFormatter();
// Set the stream of the underlying BinaryWriter to our memory stream.
OutStream = _ms;
}
public void Write(Image image)
{
var ms = new MemoryStream(); //Create a memory stream to store our image bytes.
image.Save(ms, ImageFormat.Png); //Save the image to the stream.
ms.Close(); //Close the stream.
byte[] imageBytes = ms.ToArray(); //Grab the bytes from the stream.
//Write the image bytes to our memory stream
//Length then bytes
Write(imageBytes.Length);
Write(imageBytes);
}
public void WriteT(object obj)
{
//We use the BinaryFormatter to serialize our object to the stream.
_bf.Serialize(_ms, obj);
}
public byte[] GetBytes()
{
Close(); //Close the Stream. We no longer have need for it.
byte[] data = _ms.ToArray(); //Grab the bytes and return.
return data;
}
}
public class PacketReader : BinaryReader
{
// This will be used for deserializing
private BinaryFormatter _bf;
public PacketReader(byte[] data) : base(new MemoryStream(data))
{
_bf = new BinaryFormatter();
}
public Image ReadImage()
{
//Read the length first as we wrote it.
int len = ReadInt32();
//Read the bytes
byte[] bytes = ReadBytes(len);
Image img; //This will hold the image.
using (MemoryStream ms = new MemoryStream(bytes))
{
img = Image.FromStream(ms); //Get the image from the stream of the bytes.
}
return img; //Return the image.
}
public T ReadObject<T>()
{
//Use the BinaryFormatter to deserialize the object and return it casted as T
/* MSDN Generics
* http://msdn.microsoft.com/en-us/library/ms379564%28v=vs.80%29.aspx
*/
return (T)_bf.Deserialize(BaseStream);
}
}
I don't know if it is better method, I don't have experience with it, so I want to ask someone more experienced.
Is good method make images from data and send?
Thank you for any advice, I will be grateful!
Check out this CodeProject example, it seems to be what you're looking for. You'll need two separate applications, one for your server and the other for your client.
Server: Essentially all you need to do here is open up a TcpListener and receive the bytes from it. From the CodeProject article:
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
public class serv {
public static void Main() {
try {
IPAddress ipAd = IPAddress.Parse("172.21.5.99");
// use local m/c IP address, and
// use the same in the client
/* Initializes the Listener */
TcpListener myList=new TcpListener(ipAd,8001);
/* Start Listening at the specified port */
myList.Start();
Console.WriteLine("The server is running at port 8001...");
Console.WriteLine("The local End point is :" +
myList.LocalEndpoint );
Console.WriteLine("Waiting for a connection.....");
Socket s = myList.AcceptSocket();
Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
byte[] b=new byte[100];
int k=s.Receive(b);
Console.WriteLine("Recieved...");
for (int i=0;i<k;i++)
Console.Write(Convert.ToChar(b[i]));
ASCIIEncoding asen=new ASCIIEncoding();
s.Send(asen.GetBytes("The string was recieved by the server."));
Console.WriteLine("\nSent Acknowledgement");
s.Close();
myList.Stop();
}
catch (Exception e) {
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
Client: The client is pretty similar, except instead of using a TcpListener, you'd use a TcpClient. Again from CodeProject:
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Sockets;
public class clnt {
public static void Main() {
try {
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect("172.21.5.99",8001);
// use the ipaddress as in the server program
Console.WriteLine("Connected");
Console.Write("Enter the string to be transmitted : ");
String str=Console.ReadLine();
Stream stm = tcpclnt.GetStream();
ASCIIEncoding asen= new ASCIIEncoding();
byte[] ba=asen.GetBytes(str);
Console.WriteLine("Transmitting.....");
stm.Write(ba,0,ba.Length);
byte[] bb=new byte[100];
int k=stm.Read(bb,0,100);
for (int i=0;i<k;i++)
Console.Write(Convert.ToChar(bb[i]));
tcpclnt.Close();
}
catch (Exception e) {
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
This is a very basic example of how you can do some simple networking tasks in .Net; if you're planning on creating web-based applications I'd recommend you use WCF/Asp.Net.

File creation of specific length in c#

I am trying to create a new file with a specific length.
By using below code, the file gets created.
The problem is the length of the file created is 0kb's.
Also, the text under stream writer is not written in the file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
namespace Filesize
{
class Program
{
static void Main(string[] args)
{
FileInfo fi = new FileInfo(#"D:\\demotext2.txt");
StreamWriter sw = new StreamWriter(#"D:\\demotext2.txt", true);
try
{
while (fi.Length >= (2 * 1024 * 1024))
{
sw.WriteLine("Demo File");
}
}
catch (Exception ex)
{
ex.ToString();
}
}
}
}
Try to use this:
http://msdn.microsoft.com/en-us/library/system.io.filestream.setlength.aspx
using (var fs = new FileStream(strCombined, FileMode.Create, FileAccess.Write, FileShare.None))
{
fs.SetLength(oFileInfo.FileSize);
}

Writing/reading string through NetworkStream (sockets) for a chat

Sorry if this is hard to understand, trying out C# for the first time.
I am trying to make a simple public 'chat' between clients that are connected to the server. I've tried passing integers to the server and printing them out and everything was fine, however,when I switched to strings, it seems that it can only pass 1 character (because of ns.Write(converted, 0, 1);). If I increase the ns.Write to ns.Write(converted,0,10) everything crashes (both the client and the server) when I enter a message that is less than 10 characters.
Server code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
namespace MultiServeris
{
class Multiserveris
{
static void Main(string[] args)
{
TcpListener ServerSocket = new TcpListener(1000);
ServerSocket.Start();
Console.WriteLine("Server started");
while (true)
{
TcpClient clientSocket = ServerSocket.AcceptTcpClient();
handleClient client = new handleClient();
client.startClient(clientSocket);
}
}
}
public class handleClient
{
TcpClient clientSocket;
public void startClient(TcpClient inClientSocket)
{
this.clientSocket = inClientSocket;
Thread ctThread = new Thread(Chat);
ctThread.Start();
}
private void Chat()
{
byte[] buffer = new byte[10];
while (true)
{
NetworkStream ns = clientSocket.GetStream();
ns.Read(buffer,0,1);
string line = Encoding.UTF8.GetString(buffer);
Console.WriteLine(line);
}
}
}
}
Client code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
namespace Klientas
{
class Klientas
{
static void Main(string[] args)
{
while (true)
{
TcpClient clientSocket = new TcpClient("localhost", 1000);
NetworkStream ns = clientSocket.GetStream();
byte[] buffer = new byte[10];
string str = Console.ReadLine();
byte[] converted = System.Text.Encoding.UTF8.GetBytes(str);
ns.Write(converted, 0, 1);
}
}
}
}
You're best using the BinaryReader/BinaryWriter classes to correctly format and read out data. This removes the need to process it yourself. For example in the client do:
BinaryWriter writer = new BinaryWriter(clientSocket.GetStream());
writer.Write(str);
And in the server:
BinaryReader reader = new BinaryReader(clientSocket.GetStream());
Console.WriteLine(reader.ReadString());
When using BinaryReader or BinaryWriter on the same stream, and you have .NET framework version 4.5 or above, be sure to leave the underlying stream open by using the overload:
using (var w = new BinaryWriter(stream, Encoding.UTF8, true)) {}

How can I simultaneously read/write form a text file using C#?

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.
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, 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.
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).
You can't read and write from the same text file at the same time.
If you really want to use text files, why not using 2 of them:
One to read from and one to write into.
Once the read file is empty -> the read file is your new write file and vice versa.
That sounds logic, it's not possible for 2 threads to access a file as the same time, because the file is in use.
Imagine that it's even possible, you will have some very strange behaviour.
Why are you not using a lock() to make sure that only a single thread can access the file at a given time?
And with async programming, you don't need to wait until the lock is released before continueing your program.
You will have to create Threads like this
Thread thread = new Thread(yourMethod());
When you have multiple threads then what you need is ReaderWriterLockSlim. Here is the link.
It lets you to read a file by multiple threads but write the file with one Thread. I think this will solve your problem.

Categories