I have two service. 1- client 2- server. Both the services communicate through socket.
Client contains a file system watcher. Whenever the file system watcher detects new file in the specified folder it establishes the connection to sever and sends the file to server.
Server listens to a specific port and accepts the request and receives the file and saves the details to DB. And then sends the success/error message to client.
For the first time the whole system is working fine. But when the filesystemwatcher gets the 2nd file, the application generates the exception “The process can’t access the file. Its being used by another process”. Again when I debug the service there is no exception. Not able to get the exact reason of the issue.
Any help will be highly appreciated.
Client code:
namespace WindowsService1
{
public partial class Client : ServiceBase
{
string hostIPAddress = string.Empty;
string processedFilePath = string.Empty;
int hostPort;
Socket socketClient;
IPEndPoint remoteEndPoint;
FileStream fs;
public PCMParserClient()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
hostIPAddress = ConfigurationManager.AppSettings["HostIP"];
hostPort = int.Parse(ConfigurationManager.AppSettings["HostPort"]);
//File system watcher
FsWatcher.Path = ConfigurationManager.AppSettings["FileWatcherPath"];
processedFilePath = ConfigurationManager.AppSettings["ProcessedFilePath"];
}
protected override void OnStop()
{
}
private void FsWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
{
try
{
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress remoteIPAddress = IPAddress.Parse(hostIPAddress);
remoteEndPoint = new IPEndPoint(remoteIPAddress, hostPort);
//Establish the connection to server
socketClient.Connect(remoteEndPoint);
EventLog.WriteEntry(e.Name+"before");
**//the below line generates teh exception for 2nd time onwards**
using (fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
EventLog.WriteEntry("1");
//Convert the file name in form of byte
byte[] fileNameByte = Encoding.ASCII.GetBytes(e.Name);
EventLog.WriteEntry(e.Name);
//4- to store the filename length(as int - 4bytes)
//8- to store the file content length(as long take 8 bytes)
int totalLength = 4 + fileNameByte.Length + 8;
//Clientdata[] reprents the data to sent to the server
//which represent the file details
byte[] clientData = new byte[totalLength];
byte[] fileNameLength = BitConverter.GetBytes(fileNameByte.Length);
byte[] fileContentLength = BitConverter.GetBytes(fs.Length);
//Copy all the data ClientData array
fileNameLength.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileContentLength.CopyTo(clientData, 4 + fileNameByte.Length);
//Send the data to server
socketClient.Send(clientData);
int byteRead = 0;
int bytesToRead = (int)fs.Length;
while (bytesToRead > 0)
{
byte[] data = new Byte[1500];
byteRead = bytesToRead > 1500 ? 1500 : bytesToRead;
int n = fs.Read(data, 0, byteRead);
//Send the data to server
socketClient.Send(data);
bytesToRead -= n;
}
fs.Flush();
//fs.Close();
//fs.Dispose();
}
//Code block to get the success/failure message from server
byte[] message = new byte[5];
int msg = socketClient.Receive(message);
else if (Encoding.ASCII.GetString(message).Contains("Error"))
{
throw new Exception("Error occured while processing the file " + e.Name);
}
}
catch (SocketException ex)
{
ExceptionLogger.LogException(ex);
}
catch (IOException ex)
{
ExceptionLogger.LogException(ex);
}
catch (Exception ex)
{
ExceptionLogger.LogException(ex);
}
finally
{
if (socketClient != null && socketClient.Connected)
{
socketClient.Close();
}
}
}
}
}
Server Code:
namespace PCMParserService
{
public partial class ParserServer : ServiceBase
{
Socket serverSocket = null;
public Timer timer1;
IPEndPoint ipEndPoint;
public HL7ParserService()
{
InitializeComponent();
timer1 = new Timer(1000);
timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
}
void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
Socket handler = null;
try
{
// The program is suspended while waiting for an incoming connection.
// This is a synchronous TCP application
handler = serverSocket.Accept();
byte[] fileDetails = new byte[1500];
//Recieve the file details
handler.Receive(fileDetails);
int fileNameLength = BitConverter.ToInt32(fileDetails, 0);
string fileName = Encoding.ASCII.GetString(fileDetails, 4, fileNameLength);
EventLog.WriteEntry(fileNameLength.ToString(), System.Diagnostics.EventLogEntryType.Information);
int fileLength = BitConverter.ToInt32(fileDetails, 4 + fileNameLength);
filePath = ConfigurationManager.AppSettings["ProcessedDirectory"];
FileStream fs = new FileStream(filePath + fileName, FileMode.Create, FileAccess.Write);
int byteRead = 0;
while (byteRead < fileLength)
{
byte[] data = new Byte[1500];
//Recieve the data and write to the file
int r = handler.Receive(data);
fs.Write(data, 0, r);
byteRead += r;
}
fs.Flush();
fs.Close();
fs.Dispose();
//-Code to Parse text file and save to db
FileStream fileStream = new FileStream(filePath + fileName, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fileStream);
///Code
fileStream.Close();
fileStream.Dispose();
sr.Close();
sbMessage.Append("</Message>");
saveFileDetails(sbMessage.ToString());
//-- End of File Parsing code
handler.Send(Encoding.ASCII.GetBytes("Done"));
}
catch (SocketException ex)
{
ExceptionLogger.LogException(ex, "Error occured while processing the file + " + filePath);
handler.Send(Encoding.ASCII.GetBytes("Error"));
}
catch (IOException ex)
{
ExceptionLogger.LogException(ex, "Error occured while processing the file + " + filePath);
handler.Send(Encoding.ASCII.GetBytes("Error"));
}
catch (SqlException ex)
{
ExceptionLogger.LogException(ex, "Error occured while processing the file + " + filePath);
handler.Send(Encoding.ASCII.GetBytes("Error"));
}
catch (Exception ex)
{
ExceptionLogger.LogException(ex, "Error occured while processing the file + " + filePath);
handler.Send(Encoding.ASCII.GetBytes("Error"));
}
}
protected override void OnStart(string[] args)
{
try
{
//The port on which the server listens
ipEndPoint = new IPEndPoint(IPAddress.Any, 8030);
//Defines the kind of socket we want :TCP
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Bind the socket to the local end point(associate the socket to local end point)
serverSocket.Bind(ipEndPoint);
//listen for incoming connection attempt
// Start listening, only allow 100 connection to queue at the same time
serverSocket.Listen(100);
timer1.Start();
}
catch (SocketException ex)
{
ExceptionLogger.LogException(ex, string.Empty);
}
catch (Exception ex)
{
ExceptionLogger.LogException(ex, string.Empty);
}
}
protected override void OnStop()
{
timer1.Stop();
}
protected override void OnPause()
{
timer1.Stop();
}
protected override void OnContinue()
{
timer1.Start();
}
protected override void OnShutdown()
{
timer1.Stop();
}
}
}
This is usually caused by the process writing the file having not finished writing the file, and thus releasing the file, when the
FileSystemWatchernotifies you that there’s a new file in the watched directory.Options to mitigate this include:
You won’t usually see this issue during debugging/testing because you’ll be either manually copying files into the watched directory or stepping-through your code slowly enough that the file has finished being written prior to the attempt to open it.