Как скопировать файл, когда он используется другим процессом
Можно ли одновременно копировать файл, который используется другим процессом?
Я спрашиваю, потому что, когда я пытаюсь скопировать файл, используя следующий код, возникает исключение:
System.IO.File.Copy(s, destFile, true);
Исключение составляет:
Процесс не может получить доступ к файлу "D:\temp\1000000045.zip", потому что он используется другим процессом.
Я не хочу создавать новый файл, просто хочу скопировать его или удалить. Возможно ли это?
Ответы
Ответ 1
Пример (примечание: я только что объединил два результата Google, возможно, вам придется исправить незначительные ошибки;))
Важной частью является FileShare.ReadWrite
при открытии FileStream.
Я использую аналогичный код для открытия и чтения документов 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
Чтобы создать копию файла, который read- и/или заблокирован для записи другим процессом в Windows, самое простое (и, вероятно, единственное) решение состоит в том, чтобы использовать службу теневого копирования томов (VSS).
Служба теневого копирования томов сложна и трудна для вызова из управляемого кода. К счастью, некоторые замечательные парни создали библиотеку классов .NET для этого. Ознакомьтесь с проектом Alpha VSS на CodePlex: http://alphavss.codeplex.com.
РЕДАКТИРОВАТЬ
Как и во многих проектах CodePlex, Alpha VSS перешла на GitHub. Проект сейчас здесь: https://github.com/alphaleonis/AlphaVSS.
Ответ 3
Вам следует изучить и выяснить, какой процесс блокирует файл. Если этот процесс не является вашим, у вас нет способа решить проблему. Конечно, вы можете применить некоторые хаки и вручную заблокировать блокировку файлов, но, скорее всего, этот подход приведет к непредсказуемым последствиям. Если процесс принадлежит вам, попробуйте разблокировать файл или заблокировать его с доступом к общедоступному доступу.
[EDIT]
Самый простой способ обнаружить процесс блокировки - использовать Process Explorer. Запустить его и ввести имя файла в диалоговом окне Find->Find Handle or DLL...
. В результатах поиска вы сможете увидеть, какой процесс блокирует ваш файл.
Вы также можете выполнить эту работу на С#, чтобы проверить это: Какой процесс блокирует файл?. Также
Ответ 4
Нет, вы не можете. Некоторые программы не будут блокировать файл для чтения, но если это так, вы не можете попасть в файл, не убивая другую программу.
Ответ 5
Ну, другой вариант - скопировать заблокированный файл куда-нибудь, используя класс Process, и вызвать CMD, чтобы использовать команду "copy". В большинстве случаев команда "copy" сможет сделать копию файла, даже если он используется другим процессом, минуя проблему С# File.Copy.
Пример:
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...