【问题标题】:System.IO.IOException: The process cannot access the file 'file_name'System.IO.IOException:进程无法访问文件“file_name”
【发布时间】:2011-05-06 21:44:44
【问题描述】:

我的windows服务中有一个方法如下:

System.IO.File.Copy(path, ConfigurationManager.AppSettings["BulkInsertGiftRegisterCreatorDirectory"] + System.IO.Path.GetFileName(path));

Loyalty.Entity.Base.FileInfo file = new Loyalty.Entity.Base.FileInfo();
file.FileName = path;
request.Object = file;

ResponseBase response = new ResponseBase(request);
RequestConnection connection = new RequestConnection("cn");
FileManager fileManager = new FileManager(request, connection);
response = fileManager.OfflineGiftRegisterBulkInsert();

System.IO.File.Delete(ConfigurationManager.AppSettings["BulkInsertGiftRegisterCreatorDirectory"] + System.IO.Path.GetFileName(path));

// here is the part of stored procedure that uses file
SELECT @SCRIPT= 'BULK INSERT GIFT_CARD.GIFT_TEMP'
                            +' FROM '''
                            + @FILE_PATH
                            +''' WITH ('
                                 +'FIELDTERMINATOR = '','','
                                 + 'KEEPNULLS'
                            +');'

我可以手动从文件系统中删除文件,但是这段代码告诉我“糟糕!System.IO.IOException:进程无法访问文件'filename' 因为它正被另一个进程使用。”

我已经在 stackoverflow 和其他地方搜索了类似的问题。但我找不到任何可以帮助我的东西。复制或删除方法返回 void,并且我的代码中没有要处理的流。

我该如何解决?

提前致谢。

【问题讨论】:

  • “做其他事情”部分在做什么?我假设它正在对正在复制/删除的文件做 something 。我觉得这件事在这里很重要。
  • 您的 Window 服务是否以与您相同的身份运行?如果没有,可能是 Window 的服务没有删除文件的权限。
  • 我调用了一个存储过程,它使用文件的路径批量插入文件包含的行。
  • @anilca:这意味着文件被打开(可能是通过执行存储过程的方法,或者通过存储过程)。确保它已正确关闭。如果您出示您的代码,我们可以帮助您找出问题所在。
  • @ChrisNel52 我正在以 Windows 服务使用的同一用户身份登录。

标签: c# file file-io process


【解决方案1】:

这是一种检查文件是否正在使用的方法:

public static System.Boolean FileInUse(System.String file)
{
    try
    {
        if (!System.IO.File.Exists(file)) // The path might also be invalid.
        {
            return false;
        }

        using (System.IO.FileStream stream = new System.IO.FileStream(file, System.IO.FileMode.Open))
        {
            return false;
        }
    }
    catch
    {
        return true;
    }
}

另外,等待我制作的文件:

public static void WaitForFile(System.String file)
{
    // While the file is in use...
    while (FileInUse(file)) ; // Do nothing.
}

我希望这会有所帮助!

【讨论】:

  • 这不是 Windows 应用程序@Vercas。这是一个 Windows 服务。
  • @anilca 那么请原谅。我从未使用过 Windows 服务,所以我只会让它什么都不做。
【解决方案2】:

在查看代码之前,您可能希望使用process explorer 来确定哪个进程具有句柄。这可能会排除一些你没有想到的问题

更新

由于您使用的是计时器,因此您必须确保您的方法是可重入的并且您没有任何竞争条件。例如计时器的滴答声比您处理事件的速度快。

this question 还有 this answer

【讨论】:

    【解决方案3】:

    更好的解决方案是在使用 Vercas 展示的函数 FileInUse 之前添加这两行代码:

    GC.Collect();
    GC.WaitForPendingFinalizers();
    

    【讨论】:

    • 请解释为什么这是一个更好的解决方案。另外,一般来说,答案应该能够独立存在。现在,这看起来更像是评论或回复,而不是答案。
    • 我说这是一个更好的解决方案,因为我测试了它。我遇到了同样的问题, File.Copy 后跟 File.Delete 会给我错误。首先,我仅使用“FileInUse”进行了测试,并且成功了。但是系统需要 10 到 15 秒才能删除文件。然后我用我在这里分享的线路进行了测试,它在某些情况下有效,而另一些则无效。所以我结合了两种解决方案:首先我调用了我在这里共享的两行,然后用函数“FileInUse”测试了文件,最后调用了“File.Delete”。它就像一个魅力,文件几乎立即被删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    相关资源
    最近更新 更多