【问题标题】:Can't get around IOException error: Cannot access the file无法绕过 IOException 错误:无法访问文件
【发布时间】:2017-05-26 19:58:27
【问题描述】:

我很难弄清楚这个 IOException。直到大约两个月前,这种方法曾经完美无瑕。我对它所做的唯一更改是将解析的文件移动到另一个文件夹,这也工作了一段时间。现在每次自定义 Windows Filewatcher 服务访问此方法时,我都会收到以下错误消息:

There was an Input Output file error: System.IO.IOException: The process cannot access the file '\\mkfiler01\ops\Envcom\EXEC\ENVCOM\Lab\COD\Exports\DataLog\DL_DR6000_1601329_2017-Jan-10_12_15_01.csv' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
   at System.IO.StreamReader..ctor(String path, Encoding encoding)
   at System.IO.File.ReadLines(String path)
   at COD_Automation.COD_AUTO.ParseData(String filePath)

我无法弄清楚它可能是什么进程,因为它在写入日志后一开始就崩溃了。我们的仪器会创建 .csv 文件并将其发送到正在监视的网络文件夹位置。然后启动服务。解析是服务中发生的第一件事。我将不胜感激这方面的任何帮助。

解析方法的代码如下:

public void ParseData(String filePath)
    {
        Write2LogFile("The parsing of " + filePath + " has begun.");

        //Create a dictionary collections with int keys (rowNums) and String values (each line of Strings)
        Dictionary<int, String> eachCSVLine = new Dictionary<int, string>();

        //String array that holds the contents of the specified row
        String[] lineContent;

        int rowNum = 1;
        try
        {
            /*loop through each line of the csv file, add it the collection
            *and iterate the row number*/
            foreach (string line in File.ReadLines(filePath))
            {
                eachCSVLine.Add(rowNum, line);
                rowNum++;
            }

            //Get the required line and split it by "," into an array
            if (eachCSVLine.ContainsKey(5))
            {
                String reqLine = eachCSVLine[5];
                lineContent = reqLine.Split(',');
            }
            else
            {
                String reqLine = eachCSVLine[4];
                lineContent = reqLine.Split(',');
            }

            /*Get the required values(index 2 for parsed Operator ID, index 3 for parsed Sample Number, 
             * index 11 for Sample Result, index 8 for provided Dilution)*/
            AnalysisInitials = lineContent.GetValue(2).ToString();
            SampNum = lineContent.GetValue(3).ToString();      //sample number            

            String result = lineContent.GetValue(11).ToString();
            String dilute = lineContent.GetValue(8).ToString();
            Dilution = Double.Parse(dilute);
            SampResult = Int32.Parse(result);    //sample result

            Write2LogFile("The following result data from " + filePath + " was just parsed: " + AnalysisInitials + "," +
                SampNum + "," + Dilution.ToString() + "," + SampResult.ToString());

            //move the parsed file to the parsed folder
            //File.Move(filePath, parsedPath);
            //Write2LogFile("The following file has been moved to the parsed folder: " + filePath);
        }
        catch (KeyNotFoundException ke)
        {

            Write2LogFile("The data elements could not be accessed from the collection because of the following: " +
                ke.GetBaseException());
            SendMail("The data elements could not be accessed from the collection because of the following: " + ke.GetBaseException());
        }
        catch (ArgumentNullException an)
        {

            Write2LogFile("The was a problem with looping through the " + filePath + " because of the following: " +
                an.GetBaseException());
            SendMail("The was a problem with looping through the " + filePath + " because of the following: " +
                an.GetBaseException());
        }
        catch (ArgumentException ae)
        {

            Write2LogFile("There was a problem with looping through the " + filePath + " because of the following: " +
                ae.GetBaseException());
            SendMail("There was a problem with looping through the " + filePath + " because of the following: " +
                ae.GetBaseException());
        }
        catch (InvalidCastException ce)
        {

            Write2LogFile("The value could not be casted or converted because of the following: " +
                ce.GetBaseException());
            SendMail("The value could not be casted or converted because of the following: " +
                ce.GetBaseException());
        }
        catch (IOException ie)
        {

            Write2LogFile("There was an Input Output file error: " +
                ie.GetBaseException());
            SendMail("There was an Input Output file error: " +
                ie.GetBaseException());
        }

    }

【问题讨论】:

  • 文件是否可能仍在写入中?看到这个SO
  • “我们的仪器会创建 .csv 文件并将其发送到正在监视的网络文件夹位置”——您确定仪器正在释放该文件吗?此外,它位于网络共享上意味着任何具有访问权限的用户都可以打开它,这会锁定它。您应该尝试the code here,在其中使用FileStreamFileMode.Open, FileAccess.Read, FileShare.ReadWrite,即使它被另一个进程打开,您也应该可以读取它(如果您正在阅读另一个进程正在写入,请注意不过)。
  • 仅供参考 - 我使用 sysinterals handle cli 工具来调试这种东西,v 有用(5 分钟前刚用过)

标签: c# ioexception system.io.fileinfo


【解决方案1】:

我认为这里有一位大师为您的问题提供了一个很好的答案:

https://stackoverflow.com/a/39142959/4619012

从这里备份:

https://stackoverflow.com/a/39143086/4619012

这是 ReadLines() 实现中的一个已知错误...

【讨论】:

    【解决方案2】:

    感谢量化。我确实更改了我的代码以包含 Using 语句(我通常使用)和 Filestream。它现在有效。我仍在测试服务,但我将下面的代码部分更改为它下面的代码。

    旧代码:

    /*loop through each line of the csv file, add it the collection
            *and iterate the row number*/
            foreach (string line in File.ReadLines(filePath))
            {
                eachCSVLine.Add(rowNum, line);
                rowNum++;
            }
    

    新代码:

    /*loop through each line of the csv file, add it the collection
                *and iterate the row number*/
                using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        string currentLine;
                        while ((currentLine = reader.ReadLine()) != null)
                        {
                            eachCSVLine.Add(rowNum, currentLine);
                            rowNum++;
                        }
                    }
                }
    

    解决方案很有意义。这只是为了我的一生,我看不出什么进程甚至可以控制文件,以及为什么在没有这些问题的情况下之前工作。不过,这行得通。再次感谢您的意见。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多