用于重命名的C#DirectoryInfo.MoveTo有时会抛出IOException

时间:2016-07-18 18:32:06

标签: c# windows file permissions filesystems

我正在尝试使用DirectoryInfo.MoveTo()重命名我刚刚解压缩Zip目录的目录。大多数情况下,操作会抛出错误为Access to the path '...' is denied.的IOException。有时,操作有效,但我还没有能够关联任何支持这种情况的条件。我已经检查了很多关于同样错误的论坛帖子和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对象仍然会引发错误。

我真的很难过这个。请帮忙。

澄清: 我正在运行Windows 7,这个程序是在.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

1 个答案:

答案 0 :(得分:0)

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

  1. 将文件解压缩到临时目录。
  2. 将文件从临时目录复制到目标目录
  3. 删除临时目录
  4. //计算目录名称     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);
        }
    }