以下代码给我一个 System.IO.IOException ,并显示消息“进程无法访问该文件”。

private void UnPackLegacyStats()
{
  DirectoryInfo oDirectory;
  XmlDocument oStatsXml;

  //Get the directory
  oDirectory = new DirectoryInfo(msLegacyStatZipsPath);

  //Check if the directory exists
  if (oDirectory.Exists)
  {
    //Loop files
    foreach (FileInfo oFile in oDirectory.GetFiles())
    {
      //Check if file is a zip file
      if (C1ZipFile.IsZipFile(oFile.FullName))
      {
        //Open the zip file
        using (C1ZipFile oZipFile = new C1ZipFile(oFile.FullName, false))
        {
          //Check if the zip contains the stats
          if (oZipFile.Entries.Contains("Stats.xml"))
          {
            //Get the stats as a stream
            using (Stream oStatsStream = oZipFile.Entries["Stats.xml"].OpenReader())
            {
              //Load the stats as xml
              oStatsXml = new XmlDocument();
              oStatsXml.Load(oStatsStream);

              //Close the stream
              oStatsStream.Close();
            }

            //Loop hit elements
            foreach (XmlElement oHitElement in oStatsXml.SelectNodes("/*/hits"))
            {
              //Do stuff
            }                
          }

          //Close the file
          oZipFile.Close();
        }
      }

      //Delete the file
      oFile.Delete();
    }
  }
}

我正在努力查看文件仍然可以被锁定的位置。所有可能持有文件句柄的对象都位于 using 块中并且被显式关闭。

这是否与使用 FileInfo 对象而不是静态 GetFiles 方法返回的字符串有关?

有任何想法吗?

有帮助吗?

解决方案

我假设你在oFile.Delete呼叫得到错误。我能够重现此错误。有趣的是,当该文件是的zip文件仅发生错误。这是你所看到的行为?

看来,C1ZipFile.IsZipFile呼叫没有释放文件时,它不是一个zip文件。我可以通过使用一个FileStream,而不是传递文件路径作为字符串(IsZipFile功能可以接受),以避免这个问题。

所以下面的修改您的代码似乎工作:

if (oDirectory.Exists)
{
    //Loop files
    foreach (FileInfo oFile in oDirectory.GetFiles())
    {
        using (FileStream oStream = new FileStream(oFile.FullName, FileMode.Open))
        {
            //Check if file is a zip file
            if (C1ZipFile.IsZipFile(oStream))
            {
            // ...
            }
        }
        //Delete the file
        oFile.Delete();
    }
}    

在响应这一主题的原题:我不知道是否有可能知道,如果一个文件可以不尝试将其删除被删除。你总是可以写尝试删除该文件,并捕捉到该错误,如果它不能,然后返回一个布尔值,指示是否删除成功的功能。

其他提示

我没有看到你的代码有问题,一切看起来都很好。要检查问题是否出在 C1ZipFile 中,我建议您从流初始化 zip,而不是从文件初始化,因此您显式关闭流:

//Open the zip file
using (Stream ZipStream = oFile.OpenRead())
using (C1ZipFile oZipFile = new C1ZipFile(ZipStream, false))
{
    // ...

其他几个建议:

  • 您不需要调用 Close() 方法, 使用 (...), ,删除它们。
  • 移动xml处理(循环命中元素)outsize zip处理,即zip 文件关闭后,请尽可能少地保持文件打开状态。

我只是猜测:你确信oZipFile.Close()就足够了?也许你有打电话oZipFile.Dispose()或oZipFile.Finalize(),以确保它实际上已发布的资源。

更多,则它不会被设置有可能的,任何时候你访问的托管代码(流,文件等),您必须处理它们之外的东西。我学会了Asp.NET和图像文件的硬盘的方式,它会填满你的记忆,崩溃的服务器等。

在完整性的利益,我是冒充我的工作代码的变化从多个源来了。

private void UnPackLegacyStats()
{
  DirectoryInfo oDirectory;
  XmlDocument oStatsXml;

  //Get the directory
  oDirectory = new DirectoryInfo(msLegacyStatZipsPath);

  //Check if the directory exists
  if (oDirectory.Exists)
  {
    //Loop files
    foreach (FileInfo oFile in oDirectory.GetFiles())
    {
      //Set empty xml
      oStatsXml = null;

      //Load file into a stream
      using (Stream oFileStream = oFile.OpenRead())
      {
        //Check if file is a zip file
        if (C1ZipFile.IsZipFile(oFileStream))
        {
          //Open the zip file
          using (C1ZipFile oZipFile = new C1ZipFile(oFileStream, false))
          {
            //Check if the zip contains the stats
            if (oZipFile.Entries.Contains("Stats.xml"))
            {
              //Get the stats as a stream
              using (Stream oStatsStream = oZipFile.Entries["Stats.xml"].OpenReader())
              {
                //Load the stats as xml
                oStatsXml = new XmlDocument();
                oStatsXml.Load(oStatsStream);
              }
            }
          }
        }
      }

      //Check if we have stats
      if (oStatsXml != null)
      {
        //Process XML here
      }

      //Delete the file
      oFile.Delete();
    }
  }
}

我从中学到的主要教训是管理在一个地方调用代码文件的访问,而不是让其他组件管理自己的文件访问。当你想再次使用该文件中的其他组成部分已经完成了它的任务后,这是最apropriate。

尽管这需要在流被设置在更小的代码可以清楚地看到(在使用结束时),与具有信任一个组件已经正确地设置在所述流的

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top