用于重命名的C#DirectoryInfo.MoveTo有时会引发IOException

本文关键字:IOException 重命名 C#DirectoryInfo MoveTo 用于 | 更新日期: 2023-09-27 17:57:27

我正试图使用DirectoryInfo.MoveTo()重命名刚刚提取Zip存档的目录。大多数情况下,该操作会引发IOException,并返回错误Access to the path '...' is denied.。偶尔,操作会起作用,但我无法关联任何支持这一点的条件。我已经查看了许多关于这个错误的论坛帖子和StackOverflow问题,但我仍然无法解决这个问题。我确信它不是计算机权限。所有这些文件和文件夹都具有完全的读/写权限,我已尝试以管理员身份运行该程序。

这是我的代码:

// Compute directory names
string directoryPathWithPrefix = Path.Combine(this.OutputDirectory.FullName,
    "TEMP_ " + Path.GetFileNameWithoutExtension(compressedData.FullName));
string directoryPathWithoutPrefix = Path.Combine(this.OutputDirectory.FullName,
    Path.GetFileNameWithoutExtension(compressedData.FullName));
// Extract file to new directory
ZipFile.ExtractToDirectory(compressedData.FullName, directoryPathWithPrefix);
// Add tag for UploadId
File.Create(Path.Combine(directoryPathWithPrefix,
    upload.UploadId.ToString() + ".UPLOADID")).Close();
// Rename file
DirectoryInfo oldDir = new DirectoryInfo(directoryPathWithPrefix);
oldDir.MoveTo(directoryPathWithoutPrefix);

我曾尝试使用Process Explorer监视目录的句柄,但未能从中找到任何有用的数据。使用directory.Move()或在using块内创建ZipArchive对象仍然会引发错误。

我真的被这个难住了。请帮忙。

澄清:我运行的是Windows7,这个程序是在.NET 4.5 下构建的

这是我收到的错误:

System.IO.IOException occurred
  HResult=-2146232800
  Message=Access to the path '{PATH}' is denied.
  Source=mscorlib
  StackTrace:
       at System.IO.DirectoryInfo.MoveTo(String destDirName)
       at DataImporter.ImportFDUU(FileSystemInfo uploadToImport, Message& reportMessage) in {CODE FILE}:line 380
  InnerException: 

在目录上运行cacls会返回以下信息:

            BUILTIN'Administrators:(OI)(CI)F
            {MY USER}:(OI)(CI)F

用于重命名的C#DirectoryInfo.MoveTo有时会引发IOException

我终于解决了这个问题。ZipFile.ExtractToDirectory()存在一些奇怪的故障,当它完成提取时,它不会释放对目录中文件的访问权限。为了解决这个问题,我更改了我的代码如下:

  1. 将文件提取到临时目录中
  2. 将文件从临时目录复制到目标目录
  3. 删除临时目录

//计算目录名string directoryPathWithPrefix=Path.Combine(this.SeparatorInputDirectory.FullName,"TEMP_"+Path.GetFileNameWithoutExtension(compressedFlightData.FullName));

string directoryPathWithoutPrefix = Path.Combine(this.SeparatorInputDirectory.FullName,
    Path.GetFileNameWithoutExtension(compressedFlightData.FullName));
string tempDirectoryPath = Path.Combine(TempDirectoryPath, Path.GetDirectoryName(directoryPathWithoutPrefix));
// Extract file to new directory in the separator input directory
ZipFile.ExtractToDirectory(compressedFlightData.FullName, tempDirectoryPath);
// Add tag for UploadId
File.Create(Path.Combine(tempDirectoryPath,
    upload.UploadId.ToString() + ".UPLOADID")).Close();
// Rename file to trigger separation
DirectoryCopy(tempDirectoryPath, directoryPathWithPrefix);
Directory.Move(directoryPathWithPrefix, directoryPathWithoutPrefix);
public static void DirectoryCopy(string sourceDirName, string destDirName)
{
    // Get the subdirectories for the specified directory.
    DirectoryInfo dir = new DirectoryInfo(sourceDirName);
    if (!dir.Exists)
    {
        throw new DirectoryNotFoundException(
            "Source directory does not exist or could not be found: "
            + sourceDirName);
    }
    DirectoryInfo[] dirs = dir.GetDirectories();
    // If the destination directory doesn't exist, create it.
    if (!Directory.Exists(destDirName))
    {
        Directory.CreateDirectory(destDirName);
    }
    // Get the files in the directory and copy them to the new location.
    FileInfo[] files = dir.GetFiles();
    foreach (FileInfo file in files)
    {
        string tempPath = Path.Combine(destDirName, file.Name);
        file.CopyTo(tempPath, false);
    }
    // Copy subdirectories and their contents to new location.
    foreach (DirectoryInfo subDir in dirs)
    {
        string tempPath = Path.Combine(destDirName, subDir.Name);
        DirectoryCopy(subDir.FullName, tempPath);
    }
}