简体   繁体   English

并发读取写入文件

[英]Concurrency reading writing files

Currently I am writing the windows service to process massive xml files and save info from xml file to database. 目前,我正在编写Windows服务,以处理大量的xml文件并将信息从xml文件保存到数据库。 There are 3 machines running the same services that point to the same share location. 有3台运行相同服务的计算机指向相同的共享位置。 I always got exception that File Not Found during the process and don't know how to solve this problems. 在此过程中,我总是会遇到“找不到文件”的异常情况,并且不知道如何解决此问题。 I tried to get all file from the directory and rename those files based on the machine name and allow each machine to process it own set of files but still suffer from File Not Found exception. 我试图从目录中获取所有文件,然后根据计算机名称重命名这些文件,并允许每台计算机处理自己的文件集,但仍然遭受“找不到文件”异常的困扰。 Could anyone show me the proper way to deal with this. 谁能告诉我解决这个问题的正确方法。

Thank you. 谢谢。

Code

if (Directory.Exists(folder))
{
  string pattern = ".xml";
  string machineName = System.Environment.MachineName;
  string[] files = Directory.GetFiles(folder, pattern, SearchOption.AllDirectories);  
  newExt = string.Format("{0}.{1}", machineName, newExt);
  for (int i = 0; i < files.Length; i++)
  {
      if (files[i].Contains(machineName))
      {
           //replace this new extension
           files[i].Replace(machineName + ".", "");
      }
      else
      {
           files[i] = ChangeExtension(files[i], newExt, true);
      }
  }
  IEnumerable<string> sortedFiles = files.Where(f => !string.IsNullOrEmpty(f) && f.Contains(machineName))
                                         .OrderBy(f => f, Sorter);
}

It's hard to see what's happening without looking at your code, but I'll speculate that the three individual servers get a directory listing, select a file from that listing to work on, and in the mean time a different server has renamed the file because the other server decided to start working on the file. 不查看代码就很难看到正在发生的事情,但是我推测这三台单独的服务器会得到一个目录列表,从该列表中选择一个文件进行处理,与此同时,另一台服务器已重命名该文件,因为另一台服务器决定开始处理该文件。

If this happens infrequently, you can ignore the Exception (assuming my explanation is correct). 如果这种情况很少发生,则可以忽略该异常(假设我的解释正确)。 If this happens frequently you will need to explain in more detail what you are doing. 如果这种情况经常发生,您将需要更详细地说明自己在做什么。

You can minimize contention for the same file by having each server sort the file listing in a different way (eg one AZ, the second ZA, the third LZ, AJ, ...) and then pick the top one in the sort order to work on. 通过让每个服务器以不同的方式对文件列表进行排序(例如,一个AZ,第二个ZA,第三个LZ,AJ等),然后按排序顺序选择最上面的一个,可以最大程度地减少同一文件的争用。从事于。

Could you, please, explain with what names files appear in the directory? 您能否解释一下目录中出现了哪些名称文件?

  1. If files already have the target machinename in their names it is enough for each machine to process only those named files (or not??). 如果文件名称中已经有目标计算机名,则每台计算机仅处理那些命名文件就足够了(或没有?)。
  2. If files appear without any special machinename specified, it looks like a race among the working services, who captures a file first. 如果文件显示时未指定任何特殊的机器名,则看起来就像工作服务之间的竞争,谁先捕获了文件。 Then your exception seems to be expectable (just as Eric J. said), and you'd just try..catch it and omit the file. 然后,您的异常似乎是可以预期的(就像Eric J.所说的那样),您只需尝试..catch它并忽略文件。 It is normall and some other service has already captured that file. 这是正常的,并且其他一些服务已经捕获了该文件。 Or you could think over some resource sharing technique to avoid several services to check the directory at once time. 或者,您可以考虑采用某种资源共享技术来避免使用多个服务一次检查目录。 At least you could make some subdirectories to divide all files into some groups and make each service work with each subdirectory... 至少您可以创建一些子目录,以将所有文件划分为一些组,并使每个服务都可以与每个子目录一起使用...

PS: surely, if you feel, that I failed to catch the issue, could you, please, provide some more accurate info. PS:当然,如果您觉得我未能解决问题,请提供一些更准确的信息。

As Eric J mentioned, you could simply ignore the errors: 如Eric J所述,您可以简单地忽略以下错误:

if (Directory.Exists(folder))
{
  string pattern = ".xml";
  string machineName = System.Environment.MachineName;
  string[] files = Directory.GetFiles(folder, pattern, SearchOption.AllDirectories);  
  newExt = string.Format("{0}.{1}", machineName, newExt);

  for (int i = 0; i < files.Length; i++)
  {
      try
      {
          if (files[i].Contains(machineName))
          {
               //replace this new extension
               files[i].Replace(machineName + ".", "");
          }
          else
          {
               files[i] = ChangeExtension(files[i], newExt, true);
          }
     catch(FileNotFoundException ex)
     {   
     } 
  }

  IEnumerable<string> sortedFiles = files.Where(f => !string.IsNullOrEmpty(f) && f.Contains(machineName))
                                         .OrderBy(f => f, Sorter);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM