如何在文件被其他进程使用时复制它

时间:2022-12-21 13:29:13

Is it possible to copy a file which is being using by another process at the same time?

是否可能同时复制另一个进程正在使用的文件?

I ask because when i am trying to copy the file using the following code an exception is raised:

我这样问是因为当我试图用以下代码复制文件时,会引发一个异常:

 System.IO.File.Copy(s, destFile, true);

The exception raised is:

提出例外:

The process cannot access the file 'D:\temp\1000000045.zip' because it is being used by another process.

进程无法访问文件D:\temp\1000000045。因为它正在被另一个进程使用。

I do not want to create a new file, I just want to copy it or delete it. Is this possible?

我不想创建一个新的文件,我只想复制或删除它。这是可能的吗?

5 个解决方案

#1


30  

An Example (note: I just combined two google results, you may have to fix minor errors ;))

一个例子(注意:我只是合并了两个谷歌结果,您可能需要修复小错误;)

The important part is the FileShare.ReadWrite when opening the FileStream.

重要的部分是FileShare。打开文件流时进行读写。

I use a similar code to open and read Excel documents while excel is still open and blocking the file.

我使用类似的代码来打开和读取Excel文档,而Excel仍然是打开和阻塞文件的。

  using(var inputFile = new FileStream(
         "oldFile.txt", 
         FileMode.Open, 
         FileAccess.Read, 
         FileShare.ReadWrite))
     {
        using (var outputFile = new FileStream("newFile.txt", FileMode.Create))
        { 
            var buffer = new byte[0x10000];
            int bytes;

            while ((bytes = inputFile.Read(buffer, 0, buffer.Length)) > 0) 
            {
                outputFile.Write(buffer, 0, bytes);
            }
        }
    }

#2


6  

To create a copy of a file that is read- and/or write-locked by another process on Windows, the simplest (and probably only) solution is to use the Volume Shadow Copy Service (VSS).

要创建由Windows上的另一个进程读取和/或写锁定的文件副本,最简单(可能也是唯一)的解决方案是使用卷影子复制服务(VSS)。

The Volume Shadow Copy Service is complex and difficult to call from managed code. Fortunately, some fine chaps have created a .NET class library for doing just this. Check out the Alpha VSS project on CodePlex: http://alphavss.codeplex.com.

卷影子复制服务很复杂,很难从托管代码中调用。幸运的是,一些优秀的家伙已经为此创建了。net类库。查看关于CodePlex的Alpha VSS项目:http://alphavss.codeplex.com。

EDIT

编辑

As with many of the projects on CodePlex, Alpha VSS has migrated to GitHub. The project is now here: https://github.com/alphaleonis/AlphaVSS.

与CodePlex上的许多项目一样,Alpha VSS已经迁移到了GitHub上。项目现在在这里:https://github.com/alphaleonis/AlphaVSS。

#3


1  

No you can't. Some programs won't lock the file for reading, but if they do, you can't get to the file without killing the other program.

不,你不能。一些程序不会锁定该文件以供阅读,但如果它们这样做了,您就不能在不杀死其他程序的情况下访问该文件。

#4


1  

You should explore and find out which process is blocking the file. If this process is not yours, you have no way to solve the problem. Of course, you can apply some hacks and manually free the file lock but it's most likely that this approach will lead to unsuspected consequences. If the process is yours, try to unlock the file or lock it with share read access.

您应该研究并找出是哪个进程阻塞了文件。如果这个过程不是你的,你就没有办法解决这个问题。当然,您可以应用一些技巧并手动释放文件锁,但是这种方法很可能会导致意想不到的后果。如果进程是您的,尝试解锁文件或锁定它与共享读访问。

[EDIT]
The most easier way find out blocker process would be to use Process Explorer.Launch it and enter the file name in Find->Find Handle or DLL... dialog box. In the search results, you would be able to see which process is blocking your file. You also can do this job in C# check this: What process locks a file?. Also

[编辑]最容易找到拦截程序的方法是使用过程资源管理器。启动它并在Find->查找句柄或DLL中输入文件名…对话框。在搜索结果中,您可以看到哪个进程正在阻塞您的文件。您也可以在c#中做这个工作:什么进程锁一个文件?也

#5


0  

Well, another option is to copy the locked file somewhere by using Process class and invoke CMD to use the "copy" command. In most cases the "copy" command will be able to make a copy of the file even if it is in use by another process, bypassing the C# File.Copy problem.

另一个选项是使用Process class复制被锁定的文件,并调用CMD来使用“copy”命令。在大多数情况下,“复制”命令将能够复制文件,即使它正在被另一个进程使用,绕过c#文件。复制问题。

Example:

例子:

try
{
File.Copy(somefile)
}
catch (IOException e)
{
 if (e.Message.Contains("in use"))
                        {

                            Process.StartInfo.UseShellExecute = false;
                            Process.StartInfo.RedirectStandardOutput = true;                           
                            Process.StartInfo.FileName = "cmd.exe";
                            Process.StartInfo.Arguments = "/C copy \"" + yourlockedfile + "\" \"" + destination + "\"";
                            Process.Start();                            
                            Console.WriteLine(Process.StandardOutput.ReadToEnd());
                            Proess.WaitForExit();
                            Process.Close();                          
                        }
}

the try/catch should be added on top of your current try/catch to handle the file in use exception to allow your code to continue... 

#1


30  

An Example (note: I just combined two google results, you may have to fix minor errors ;))

一个例子(注意:我只是合并了两个谷歌结果,您可能需要修复小错误;)

The important part is the FileShare.ReadWrite when opening the FileStream.

重要的部分是FileShare。打开文件流时进行读写。

I use a similar code to open and read Excel documents while excel is still open and blocking the file.

我使用类似的代码来打开和读取Excel文档,而Excel仍然是打开和阻塞文件的。

  using(var inputFile = new FileStream(
         "oldFile.txt", 
         FileMode.Open, 
         FileAccess.Read, 
         FileShare.ReadWrite))
     {
        using (var outputFile = new FileStream("newFile.txt", FileMode.Create))
        { 
            var buffer = new byte[0x10000];
            int bytes;

            while ((bytes = inputFile.Read(buffer, 0, buffer.Length)) > 0) 
            {
                outputFile.Write(buffer, 0, bytes);
            }
        }
    }

#2


6  

To create a copy of a file that is read- and/or write-locked by another process on Windows, the simplest (and probably only) solution is to use the Volume Shadow Copy Service (VSS).

要创建由Windows上的另一个进程读取和/或写锁定的文件副本,最简单(可能也是唯一)的解决方案是使用卷影子复制服务(VSS)。

The Volume Shadow Copy Service is complex and difficult to call from managed code. Fortunately, some fine chaps have created a .NET class library for doing just this. Check out the Alpha VSS project on CodePlex: http://alphavss.codeplex.com.

卷影子复制服务很复杂,很难从托管代码中调用。幸运的是,一些优秀的家伙已经为此创建了。net类库。查看关于CodePlex的Alpha VSS项目:http://alphavss.codeplex.com。

EDIT

编辑

As with many of the projects on CodePlex, Alpha VSS has migrated to GitHub. The project is now here: https://github.com/alphaleonis/AlphaVSS.

与CodePlex上的许多项目一样,Alpha VSS已经迁移到了GitHub上。项目现在在这里:https://github.com/alphaleonis/AlphaVSS。

#3


1  

No you can't. Some programs won't lock the file for reading, but if they do, you can't get to the file without killing the other program.

不,你不能。一些程序不会锁定该文件以供阅读,但如果它们这样做了,您就不能在不杀死其他程序的情况下访问该文件。

#4


1  

You should explore and find out which process is blocking the file. If this process is not yours, you have no way to solve the problem. Of course, you can apply some hacks and manually free the file lock but it's most likely that this approach will lead to unsuspected consequences. If the process is yours, try to unlock the file or lock it with share read access.

您应该研究并找出是哪个进程阻塞了文件。如果这个过程不是你的,你就没有办法解决这个问题。当然,您可以应用一些技巧并手动释放文件锁,但是这种方法很可能会导致意想不到的后果。如果进程是您的,尝试解锁文件或锁定它与共享读访问。

[EDIT]
The most easier way find out blocker process would be to use Process Explorer.Launch it and enter the file name in Find->Find Handle or DLL... dialog box. In the search results, you would be able to see which process is blocking your file. You also can do this job in C# check this: What process locks a file?. Also

[编辑]最容易找到拦截程序的方法是使用过程资源管理器。启动它并在Find->查找句柄或DLL中输入文件名…对话框。在搜索结果中,您可以看到哪个进程正在阻塞您的文件。您也可以在c#中做这个工作:什么进程锁一个文件?也

#5


0  

Well, another option is to copy the locked file somewhere by using Process class and invoke CMD to use the "copy" command. In most cases the "copy" command will be able to make a copy of the file even if it is in use by another process, bypassing the C# File.Copy problem.

另一个选项是使用Process class复制被锁定的文件,并调用CMD来使用“copy”命令。在大多数情况下,“复制”命令将能够复制文件,即使它正在被另一个进程使用,绕过c#文件。复制问题。

Example:

例子:

try
{
File.Copy(somefile)
}
catch (IOException e)
{
 if (e.Message.Contains("in use"))
                        {

                            Process.StartInfo.UseShellExecute = false;
                            Process.StartInfo.RedirectStandardOutput = true;                           
                            Process.StartInfo.FileName = "cmd.exe";
                            Process.StartInfo.Arguments = "/C copy \"" + yourlockedfile + "\" \"" + destination + "\"";
                            Process.Start();                            
                            Console.WriteLine(Process.StandardOutput.ReadToEnd());
                            Proess.WaitForExit();
                            Process.Close();                          
                        }
}

the try/catch should be added on top of your current try/catch to handle the file in use exception to allow your code to continue...