【问题标题】:File access error when deleting删除时文件访问错误
【发布时间】:2016-08-18 01:22:23
【问题描述】:

我的代码的目的是监视一个文件夹中的 xml 文件。如果一个文件放在文件夹中,它将被读取,转换为 byte[],通过套接字发送到服务器,然后删除。

这仅在之前未发送的文件被放置在文件夹中时才有效。

示例:我发送 1.xml,一切正常,文件被删除。 我将 1.xml 粘贴到文件夹中。 文件被读取,但在删除时引发异常(由另一个
过程)。

如果我等待足够长的时间或替换文件名,它会正常工作。 我可以添加一个延迟(经过测试至少可以工作 3 秒),但这违背了我的程序的目的。

我用 Python 编写了同样的代码,它运行良好,所以我很难过。 请参阅下面的代码。谢谢你的帮助!

string[] files;
while (sending)
{
    files = Directory.GetFiles(Events_Directory, "*.xml");                    
    foreach(string file in files)
    {
        Message = System.Text.UTF8Encoding.ASCII.GetBytes(Regex.Replace(
                            File.ReadAllText(file), @"[\r\n\t ]+", ""));
        Thread.Sleep(500);
        Sock.Send(Message);
        File.Delete(file);
    }
}

【问题讨论】:

    标签: c# .net file-io


    【解决方案1】:

    您可以尝试使用 StreamReader 并在读取后显式关闭流。

    string[] files;
    while (sending)
    {
        files = Directory.GetFiles(Events_Directory, "*.xml");
        foreach (string file in files)
        {
            StreamReader IN = new StreamReader(file);
            string allText = IN.ReadToEnd();
            IN.Close();
            Message = System.Text.UTF8Encoding.ASCII.GetBytes(Regex.Replace(
                                allText, @"[\r\n\t ]+", ""));
            Sock.Send(Message);
            File.Delete(file);
        }
    }
    

    【讨论】:

    • 我试过了。实际上,我最初使用的是 StreamReader,但后来转到 File.ReadAllText 以避免任何打开/关闭错误。单步执行代码时,直到第二次删除文件时才会引发异常。
    • 第二次删除文件是什么意思?我只看到 1 个要求删除的电话。
    • 它在一个循环中。假设发送 = True。因此,只要发送为 True(用户控制),它就会监视该文件夹“Events_Directory”中的 xml 文件。如果我将文件“1.xml”粘贴到文件夹中,它会做的一切都很好,包括删除。现在,虽然仍在该循环中,但如果我粘贴相同的文件“1.xml”,一旦我第二次到达删除调用,我就会得到异常。我希望这能更好地解释它。
    • 所以你说 files = Directory.GetFiles(Events_Directory, "*.xml");给你已经被删除的文件?
    • @Brrom,我错了异常发生的位置。它不是在删除期间,而是在读取第二个(新粘贴到目录中)文件。我假设这是一个速度问题。即使程序识别出一个新文件,然后尝试打开该文件进行读取,该文件似乎也不存在。不过我修好了。见我上面的回答。感谢您的帮助!
    【解决方案2】:

    好的,所以我错了异常发生的位置。实际上是在第二次尝试读取文件之后。 我注意到,如果运行此代码的线程被终止并“重新”启动,则一切正常。所以我添加了一个变通方法,将线程本身放在一个循环中,而不是线程的方法。

            while (sending)
        {
                    Thread EventSenderThread = new Thread(() =>
                        Communications.EventSender(Event_Directory));
                    EventSenderThread.Start();
                    while (EventSenderThread.IsAlive)
                    { System.Windows.Forms.Application.DoEvents(); }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      相关资源
      最近更新 更多