一个进程无法访问文件,因为它正在被另一个进程使用

时间:2018-11-08 21:28:19

标签: c# winforms io

我意识到这个问题有几种变体,但是在复习它们时,我没有看到确切的用例,结果也出现了皱纹。

我正在做的工作是将一些BZ2压缩文件通过FTP传输到文件夹中的硬盘。然后,我解压缩每一个以供审核。最后,我想通过电子邮件将文件发送给某人,但我想先将它们放入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​​,该API会将目标目录中的所有文件压缩并压缩到存档中。

皱纹是即使我得到了例外

  

进程无法访问文件“ C:...”,因为它正在被另一个进程使用”

无论如何,它都会在我为此创建的zip子目录中创建ZIP存档。它几乎看起来像在库函数CreateFromDirectory内,但这是我通过引用访问的标准库的一部分:

  

System.IO.Compression.FileSystem。

2 个答案:

答案 0 :(得分:1)

压缩文件的destinaton目录:
@"C:\temp\logfiles\[Some Name]\Zip"

包含在源目录的路径中,是压缩操作的基本目录:
@"C:\temp\logfiles\[Some Name]

ZipFile.CreateFromDirectory包括基本Directory的SubDirectories树结构及其在创建压缩文件时的内容,因此它还会尝试压缩其创建的目标文件。当然,它无法访问,因为(正在猜测什么)正在使用。

如果将目标目录移至基本路径之外,则不会引发任何异常。

您可以将用户Temp目录用作压缩文件的临时目标,然后在完成后将其移至目标目录。

用户临时目录由Environment.GetEnvironmentVariable()返回:

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

您还需要删除Temp zip文件,并且在任何情况下都要验证它是否不存在(具有该名称的文件可能由于任何原因而存在,尝试覆盖它会导致错误)。 br />

使用用户临时目录创建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));

答案 1 :(得分:0)

如果您不处理FileHandle(或任何capsualtes所说的句柄),这种情况最经常发生*。文件句柄和网络连接是需要Disposing非托管资源的主要示例。您应该始终处置它们。

我总是认为将任何可处理资源的创建和处置分开是一个坏主意。您应该始终在同一段代码中执行“创建,使用和处置”操作(例如在Button单击内部)。理想情况下,使用用块执行此操作。高级编程人员可以忽略这一点,但是基于您的问题,我认为您在初学者方面更具优势。

*当然,除了在另一个程序中完全打开文件之外!