Процесс не может получить доступ к файлу, потому что он используется другим процессом - PullRequest
0 голосов
/ 09 ноября 2018

Я понимаю, что есть несколько вариантов этого вопроса, но при рассмотрении их я не вижу точного варианта использования, и у моего результата есть морщина.

То, что я делаю, - это отправка некоторых ZIP-файлов BZ2 на мой жесткий диск в папке. Затем я разархивирую каждый из них для просмотра. Наконец, я хочу отправить файлы кому-нибудь по электронной почте, но сначала я хочу поместить их в Zip-архив, чтобы упростить его. Ниже приведен код.

private void buttonCreateZip_Click(object sender, EventArgs e)
{
    Directory.CreateDirectory(@"C:\temp\logfiles\" + comboBoxDirectory.SelectedItem.ToString() + "\\zip\\");

    string startPath = @"C:\temp\logfiles\" + comboBoxDirectory.SelectedItem.ToString();

    string zipPath = @"C:\temp\logfiles\" + comboBoxDirectory.SelectedItem.ToString() + "\\zip\\" + comboBoxDirectory.SelectedItem.ToString() + ".zip";

    File.SetAttributes(@"C:\temp\logfiles\" + comboBoxDirectory.SelectedItem.ToString() + "\\zip\\", FileAttributes.Normal);
    File.SetAttributes(@"C:\temp\logfiles\" + comboBoxDirectory.SelectedItem.ToString() + "\\", FileAttributes.Normal);

    ZipFile.CreateFromDirectory(startPath, zipPath);
}

Я не объединяю файлы по отдельности, а использую API, который берет все файлы в целевом каталоге и упаковывает их в архив.

морщина в том, что, хотя я получаю исключение

Процесс не может получить доступ к файлу "C: ...", поскольку он используется другим процессом "

он все равно создает ZIP-архив в подкаталоге zip, который я создал для этой цели. Похоже, что она находится внутри библиотечной функции CreateFromDirectory, но это часть стандартной библиотеки, к которой я обратился по ссылке:

System.IO.Compression.FileSystem.

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Destinaton Каталог заархивированного файла:
@"C:\temp\logfiles\[Some Name]\Zip"

входит в путь к исходному каталогу, базовый каталог для операции сжатия:
@"C:\temp\logfiles\[Some Name].

ZipFile.CreateFromDirectory включает в себя древовидную структуру SubDirectories базового каталога и его содержимое при создании сжатого файла, поэтому он пытается также сжать целевой файл, который он создает. Конечно, он не может получить к нему доступ, потому что он (угадайте, что) используется.

Если вы переместите каталог назначения за пределы базового пути, он не вызовет никаких исключений.

Вы можете использовать каталог User Temp в качестве временного пункта назначения для zip-файла, а затем переместить его в каталог назначения по завершении.

Пользовательский временный каталог возвращается Environment.GetEnvironmentVariable () :

Environment.GetEnvironmentVariable("Temp", EnvironmentVariableTarget.User);

Вам также необходимо удалить zip-файл Temp и в любом случае убедиться, что он еще не существует (файл с таким именем может быть там по любой причине, и попытка перезаписать его приведет к ошибке).

Пример возможного метода создания ZipFile с использованием пользовательского временного каталога:

string SourceFolder = @"C:\temp\logfiles\";
string DestinationFolder = @"C:\temp\logfiles\Zip";
string ZippedFileName = "ZippedFile.zip";

string UserTempFolder = Environment.GetEnvironmentVariable("Temp", EnvironmentVariableTarget.User);
string ZippedTempFile = Path.Combine(UserTempFolder, ZippedFileName);
if (File.Exists(ZippedTempFile)) { File.Delete(ZippedTempFile); }

ZipFile.CreateFromDirectory(SourceFolder, ZippedTempFile);

Directory.CreateDirectory(DestinationFolder);

File.Move(ZippedTempFile, Path.Combine(DestinationFolder, ZippedFileName));
0 голосов
/ 09 ноября 2018

Это происходит чаще всего *, если вы не избавляетесь от FileHandle (или от того, что инкапсулирует указанный дескриптор).Файловые дескрипторы и сетевые подключения являются основными примерами неуправляемого ресурса, для которого требуется Утилизация .Вы всегда должны ими распоряжаться.

Я всегда считаю плохой идеей разделять создание и использование любого одноразового ресурса.Вы всегда должны создавать, использовать и удалять в одном и том же фрагменте кода (как внутри этого нажатия кнопки).В идеале сделать это с помощью блока-использования.Продвинутые программисты могут это игнорировать, но, исходя из вашей проблемы, я думаю, что вы в большей степени относитесь к новичкам.

* Конечно, кроме файла, открытого в другой Программе!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...