如何读取文件并配置streamReader对象? [英] How to read file and dispose streamReader object?

查看:81
本文介绍了如何读取文件并配置streamReader对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写程序,在文件更新时从csv文件中读取数据。现在我得到了简单的错误,即这个OnChanged事件在文件更新完成一次时触发两次.bellow是我的代码。



I am writing program which reads data from csv file when file update. Now i got simple error i.e this "OnChanged" event fires two times as file update done one time.bellow is my code.

  public void GetData()
        {
            try
            {
                //for (int i = 0; i >= 0; i++)
                //{
                    FileSystemWatcher watcher = new FileSystemWatcher();
                    watcher.Path = filepath;
                    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                   | NotifyFilters.FileName | NotifyFilters.DirectoryName;
                    // Only watch text files.
                    watcher.Filter = "*.csv";
                    watcher.Changed += new FileSystemEventHandler(OnChanged);
                   watcher.EnableRaisingEvents = true;
                //}
            }
            catch { }
        }

private void OnChanged(object source, FileSystemEventArgs e)
   {
       try
       {
           NetworkStream networkStream = clientSocket.GetStream();
           line = new string[] { };

           using(FileStream fs = new FileStream(e.FullPath,FileMode.Open,FileAccess.Read))
           using (StreamReader sr = new StreamReader(e.FullPath))
           {
              String [] line = sr.ReadLine().Split(',');
               for (int p = 0; p < line.Length; p++)
               {
                   b = Encoding.ASCII.GetBytes(line[p]);
                   networkStream.Write(b, 0, b.Length);
               }

               sr.Close();
               sr.Dispose();

               fs.Flush();
           }

       }
       catch { }
   }

推荐答案

据我所知,没有办法避免文件系统观察者触发多个事件,所以我已经使用解决方法来解决这个问题。



您可以尝试这样的事情。如果您对多个文件进行了大量更新,那么这并非万无一失。在这种情况下,您可能必须使用列表。

As far as I know there is no way to avoid the file system watcher from firing multiple events, so I have used work-around to solve this issue.

You can try something like this. It is not foolproof if you have a lot of updates to multiple files. In that case you might have to use a list.
private object lockObject = new object();
private string fileNameInUse = "";
private void OnChanged(object source, FileSystemEventArgs e)
{
    // Blocks the second call from being executed
    lock (lockObject)
    {
        if (fileNameInUse == e.FullPath) // This indicates that the file has already been handled.
        {
            fileNameInUse = "";
            return;
        }
        fileNameInUse = e.FullPath;

       try
       {
           NetworkStream networkStream = clientSocket.GetStream();
           line = new string[] { };
    
           using(FileStream fs = new FileStream(e.FullPath,FileMode.Open,FileAccess.Read))
           using (StreamReader sr = new StreamReader(e.FullPath))
           {
              String [] line = sr.ReadLine().Split(',');
               for (int p = 0; p < line.Length; p++)
               {
                   b = Encoding.ASCII.GetBytes(line[p]);
                   networkStream.Write(b, 0, b.Length);
               }
    
               sr.Close();
               sr.Dispose();
    
               fs.Flush();
           }
    
       }
       catch { }
    }
}



我希望我错了,有更好的解决方案。



[更新]

An替代解决方案


I hope I am wrong and there is a better solution.

[UPDATE]
An alternative solution

private object lockObject = new object();
private void OnChanged(object source, FileSystemEventArgs e)
{
    // Temporary turn off raising new events
    watcher.EnableRaisingEvents = false;
    // Blocks the second call from being executed
    lock (lockObject)
    {
       try
       {
           NetworkStream networkStream = clientSocket.GetStream();
           line = new string[] { };
    
           using(FileStream fs = new FileStream(e.FullPath,FileMode.Open,FileAccess.Read))
           using (StreamReader sr = new StreamReader(e.FullPath))
           {
              String [] line = sr.ReadLine().Split(',');
               for (int p = 0; p < line.Length; p++)
               {
                   b = Encoding.ASCII.GetBytes(line[p]);
                   networkStream.Write(b, 0, b.Length);
               }
    
               sr.Close();
               sr.Dispose();
    
               fs.Flush();
           }
    
       }
        catch (Exception ex)  // It is always a bad idea to hide exceptions
        {
            MessageBox.Show(ex.ToString());
        }
        finally
        {
            // Restore raising events
            watcher.EnableRaisingEvents = true;
        }
    }
}


这篇关于如何读取文件并配置streamReader对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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