System.IO.IOException:进程无法访问文件'file_name'

时间:2010-11-08 21:23:33

标签: c# file file-io process

我的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'
                            +');'

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

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

我该如何解决?

提前致谢。

3 个答案:

答案 0 :(得分:5)

以下是检查文件是否正在使用的方法:

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.
}

我希望这有帮助!

答案 1 :(得分:4)

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

更新

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

参见this question this answer

答案 2 :(得分:1)

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

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