Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 进程无法访问文件,因为另一个进程正在使用该文件_C#_Winforms_Io - Fatal编程技术网

C# 进程无法访问文件,因为另一个进程正在使用该文件

C# 进程无法访问文件,因为另一个进程正在使用该文件,c#,winforms,io,C#,Winforms,Io,我意识到这个问题有几种变体,但在回顾它们时,我没有看到我的确切用例,我的结果也有瑕疵 我正在做的是将一些BZ2压缩文件FTPing到我的硬盘文件夹中。然后我将每个文件解压缩以供审阅。最后,我想通过电子邮件将文件发送给某人,但我想先将其放入Zip存档中,以使其更简单。下面是代码 private void buttonCreateZip_Click(object sender, EventArgs e) { Directory.CreateDirectory(@"C:\temp\logfil

我意识到这个问题有几种变体,但在回顾它们时,我没有看到我的确切用例,我的结果也有瑕疵

我正在做的是将一些BZ2压缩文件FTPing到我的硬盘文件夹中。然后我将每个文件解压缩以供审阅。最后,我想通过电子邮件将文件发送给某人,但我想先将其放入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


如果您不处置文件句柄(或任何封装所述句柄),这种情况最常见。文件句柄和网络连接是需要的非托管解析的主要示例。您应该始终处置它们

我总是认为拆分任何可处置资源的创建和分配是一个坏主意。你应该总是在同一段代码中创建、使用和处理(就像在那个按钮内点击)。高级程序员可以忽略这一点,但基于你的问题,我认为你更倾向于初学者


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

压缩文件的目标目录:
@“C:\temp\logfiles\[姓名]\Zip”

包含在源目录的路径中,压缩操作的基本目录:
@“C:\temp\logfiles\[一些名字]

包括基本目录的子目录树结构及其在创建压缩文件时的内容,因此它还尝试压缩正在创建的目标文件。当然,它无法访问它,因为它(猜猜看)正在使用中。

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

您可以使用User
Temp
目录作为压缩文件的临时目标,然后在压缩完成后将其移动到目标目录。

用户临时目录由返回:

您还需要删除Temp zip文件,并在任何情况下验证该文件是否已存在(具有该名称的文件可能出于任何原因存在,尝试覆盖该文件将导致错误)。

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