2012-02-02 211 views
1

2つのサービスがあります。 1-クライアント2-サーバ。どちらのサービスもソケットを介して通信します。 クライアントにファイルシステムウォッチャーが含まれています。ファイルシステムウォッチャーは、指定されたフォルダ内の新しいファイルを検出するたびに、サーバーとの接続を確立し、そのファイルをサーバーに送信します。 サーバは特定のポートをリッスンし、要求を受け入れてファイルを受信し、その詳細をDBに保存します。成功/エラーメッセージをクライアントに送信します。プロセスが別のプロセスで使用されているため、プロセスはファイルにアクセスできません。

初めてシステム全体が正常に動作しています。しかし、ファイルシステムウォッチャーが2番目のファイルを取得すると、アプリケーションは「プロセスはファイルにアクセスできません。別のプロセスで使用されています」という例外を生成します。再びサービスをデバッグするときに例外はありません。問題の正確な理由を得ることができません。

ご協力いただければ幸いです。

クライアントコード:

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

}

サーバコード:

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

} 
} 

答えて

2

これは通常、ファイルの書き込みを完了していないたファイルの書き込みプロセスによって引き起こされ、 FileSystemWatcherがあなたに通知するとファイルを解放します監視されたディレクトリ内の新しいファイル。これを緩和するために

のオプションがあります。

  • はあなたがすぐにファイルを処理するファイル
  • を処理する前に、通知後の遅延を有するが、プロセスはファイルにアクセスできません」につながるすべてのファイルを置きますそのプロセスは別のプロセスによって「定期的に再試行されるキューに入れられます。

通常、ファイルを監視対象のディレクトリに手動でコピーするか、ファイルの試行前にファイルが書き込まれるまでゆっくりとステップ実行するため、デバッグ/テスト中にこの問題は発生しませんそれを開く。

+0

は、まさに第二の点を取得できませんでした。 – Madhusmita

0

また、別のこととして、複数のオブジェクトにどのようなアクセス権があるかを指定してファイルを開くことができます(場合によっては違いが生じる場合もあります)。代わりに書いてそう

、:あなたがFileShareオプション追加してみてください可能性があり

FileStream fileStream = new FileStream(filePath + fileName, 
             FileMode.Open, 
             FileAccess.Read); 

:適切なFileShareフラグを指定すると

FileStream fileStream = new FileStream(filePath + filename, 
             FileMode.Open, 
             FileAccess.Read, 
             FileShare.Read)) 

を、あなたはそれがあることを待たずにファイルにアクセスすることができます閉まっている。たとえば、上記の行では、FileShare.Read

読み取りのためにファイルを開くことができます。このフラグが指定されていない場合、(このプロセスまたは別のプロセスによって)読み取りのためにファイルを開く要求は、ファイルがクローズされるまで失敗します。

関連する問題