简体   繁体   中英

C# DirectoryInfo.MoveTo for Renaming Sometimes throws IOException

I am trying to use DirectoryInfo.MoveTo() to rename a directory that I have just extracted a Zip archive to. Most of the time the operation throws an IOException with the error Access to the path '...' is denied. . Occasionally, the operation works, but I haven't been able to correlate any condition that supports this. I've checked many forum posts and StackOverflow questions about this same error but I still cannot get this working. I'm sure its not computer permissions. All of these files and folders have full read/write permissions and I have tried running the program as an administrator.

Here is my code:

// 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);

I've tried using Process Explorer to monitor the handle for the directory, but haven't been able to find any useful data from it. Using Directory.Move() or creating a ZipArchive object inside a using block still raise the error as well.

I'm really stumped on this one. Please help.

Clarification: I'm running Windows 7 and this program is built under .NET 4.5

Here is the error I am receiving:

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: 

Running cacls on the directory returns this information:

            BUILTIN\Administrators:(OI)(CI)F

            {MY USER}:(OI)(CI)F

I finally figured out the issue. Some strange glitch exists with ZipFile.ExtractToDirectory() that doesn't release access to a file in the directory when it is finished extracting. To get around this I changed my code as follows:

  1. Extract the files to a temporary directory.
  2. Copy the files from the temporary directory to the destination directory
  3. Delete the temporary directory

// Compute directory names 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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM