Friday, June 11, 2010

Ошибки файловых операций - I/O Error

Исходный список можно посмотреть здесь: http://support.microsoft.com/kb/320081

Интерес представляют 4 и 6, поскольку в последнее время часто приходилось сталкиваться с этим.
Такой файл средствами .NET невозможно ни удалить, ни переименовать.
Вкратце одно из возможных решений:
1. Преобразовать файл к короткому имени.
2. Выполнить копирование файла в новое имя при помощи CopyFileEx


  1.     [Flags]
  2.     public enum CopyFileFlags : uint
  3.     {
  4.       COPY_FILE_FAIL_IF_EXISTS = 0x00000001,
  5.       COPY_FILE_RESTARTABLE = 0x00000002,
  6.       COPY_FILE_OPEN_SOURCE_FOR_WRITE = 0x00000004,
  7.       COPY_FILE_ALLOW_DECRYPTED_DESTINATION = 0x00000008
  8.     }
  9.  
  10.     public enum CopyProgressCallbackReason : uint
  11.     {
  12.       CALLBACK_CHUNK_FINISHED = 0x00000000,
  13.       CALLBACK_STREAM_SWITCH = 0x00000001
  14.     }
  15.  
  16.     public enum CopyProgressResult : uint
  17.     {
  18.  
  19.       PROGRESS_CONTINUE = 0,
  20.       PROGRESS_CANCEL = 1,
  21.       PROGRESS_STOP = 2,
  22.       PROGRESS_QUIET = 3
  23.     }
  24.  
  25.     public delegate CopyProgressResult CopyProgressRoutine(
  26.       long totalFileSize,
  27.       long totalBytesTransferred,
  28.       long streamSize,
  29.       long streamBytesTransferred,
  30.       uint dwStreamNumber,
  31.       CopyProgressCallbackReason dwCallbackReason,
  32.       IntPtr hSourceFile,
  33.       IntPtr hDestinationFile,
  34.       IntPtr lpData);
  35.  
  36.     public static bool XCopy(string oldFile, string newFile)
  37.     {
  38.       var pbCancel = 0;
  39.       return CopyFileEx(oldFile, newFile, CopyProgressHandler, IntPtr.Zero, ref pbCancel, CopyFileFlags.COPY_FILE_RESTARTABLE);
  40.     }
  41.  
  42.     public static CopyProgressResult CopyProgressHandler(long total, long transferred, long streamSize,
  43.                                long streamByteTrans, uint dwStreamNumber,
  44.                                CopyProgressCallbackReason reason, IntPtr hSourceFile,
  45.                                IntPtr hDestinationFile, IntPtr lpData)
  46.     {
  47.       return CopyProgressResult.PROGRESS_CONTINUE;
  48.     }
  49.  
  50.     [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  51.     [return: MarshalAs(UnmanagedType.Bool)]
  52.     public static extern bool CopyFileEx(string lpExistingFileName, string lpNewFileName,
  53.                        CopyProgressRoutine lpProgressRoutine, IntPtr lpData, ref Int32 pbCancel,
  54.                        CopyFileFlags dwCopyFlags);
  55.  
  56.     [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  57.     public static extern int GetShortPathName([MarshalAs(UnmanagedType.LPTStr)] string path,
  58.                          [MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath,
  59.                          int shortPathLength);
  60.  
  61.  
  62.     public static string UPath(string path)
  63.     {
  64.       const string PreNet = @"\\?\UNC\";
  65.       const string PreLoc = @"\\?\";
  66.  
  67.       var isNetworkPath = path.StartsWith(@"\\");
  68.       var pre = isNetworkPath ? PreNet : PreLoc;
  69.       var res = path.StartsWith(pre) ? path : pre + path;
  70.  
  71.       return res.EndsWith(@"\") ? res.Substring(0, res.Length - 1) : res;
  72.     }
  73.  
  74.     public static FileInfo XCopy(FileInfo fileInfo, string target)
  75.     {
  76.       var filename = Win32IOManaged.UPath(Path.GetDirectoryName(fileInfo.FullName)) + @"
  77. \" + fileInfo.Name;
  78.       var buffer = new StringBuilder(255);
  79.       var length = Win32IOManaged.GetShortPathName(filename, buffer, buffer.Capacity);
  80.  
  81.       if (length <= 0)
  82.       {
  83.         return null;
  84.       }
  85.  
  86.       var result = Win32IOManaged.XCopy(buffer.ToString(), target);
  87.       var lasterror = Marshal.GetLastWin32Error();
  88.  
  89.       if (!result || lasterror != 0)
  90.       {
  91.         return null;
  92.       }
  93.  
  94.       return new FileInfo(target);
  95.     }
* This source code was highlighted with Source Code Highlighter.

0 коммент.:

Post a Comment

Powered by Blogger.