// 获得一个目录下的全部文件名。包括子目录中的 public static List<string> GetFileNames(string strDataDir, FileNameFilterProc filter_proc = null) { DirectoryInfo di = new DirectoryInfo(strDataDir); List<string> result = new List<string>(); if (filter_proc != null && filter_proc(di) == false) return result; FileInfo[] fis = di.GetFiles(); foreach (FileInfo fi in fis) { if (filter_proc != null && filter_proc(fi) == false) continue; result.Add(fi.FullName); } // 处理下级目录,递归 DirectoryInfo[] dis = di.GetDirectories(); foreach (DirectoryInfo subdir in dis) { if (filter_proc != null && filter_proc(subdir) == false) continue; result.AddRange(GetFileNames(subdir.FullName)); } return result; }
// TODO: 可改用 PathUtil 中同名函数 /* Type: System.IO.IOException Message: 文件“c:\dp2circulation\DigitalPlatform.CirculationClient.dll”正由另一进程使用,因此该进程无法访问此文件。 Stack: 在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 在 System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite) 在 System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite) 在 dp2Circulation.GreenProgram.CopyDirectory(String strSourceDir, String strTargetDir, FileNameFilterProc filter_proc, String& strError) * */ // 拷贝目录 // return: // -2 权限不够 // -1 出错 // >=0 复制的文件总数 public static int CopyDirectory(string strSourceDir, string strTargetDir, FileNameFilterProc filter_proc, StringBuilder debugInfo, out string strError) { strError = ""; int nCount = 0; try { DirectoryInfo di = new DirectoryInfo(strSourceDir); if (di.Exists == false) { strError = "源目录 '" + strSourceDir + "' 不存在..."; return -1; } #if NO if (bDeleteTargetBeforeCopy == true) { if (Directory.Exists(strTargetDir) == true) Directory.Delete(strTargetDir, true); } #endif PathUtil.CreateDirIfNeed(strTargetDir); FileSystemInfo[] subs = di.GetFileSystemInfos(); foreach (FileSystemInfo sub in subs) { if (filter_proc != null && filter_proc(sub) == false) continue; // 复制目录 if ((sub.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { int nRet = CopyDirectory(sub.FullName, Path.Combine(strTargetDir, sub.Name), filter_proc, debugInfo, out strError); if (nRet == -1) return -1; if (nRet == -2) return -2; nCount += nRet; continue; } // 复制文件 string source = sub.FullName; string target = Path.Combine(strTargetDir, sub.Name); // 如果目标文件已经存在,并且修后修改时间相同,则不复制了 if (File.Exists(target) == true && File.GetLastWriteTimeUtc(source) == File.GetLastWriteTimeUtc(target)) { if (debugInfo != null) debugInfo.Append("目标文件 " + target + "已经存在,并且和源文件最后修改时间相同,被跳过\r\n"); continue; } // 拷贝文件,最多重试 10 次 for (int nRedoCount = 0; ; nRedoCount++) { try { File.Copy(source, target, true); if (debugInfo != null) debugInfo.Append("复制文件 " + source + " --> " + target + "\r\n"); } catch (Exception ex) { if (nRedoCount < 10) { Thread.Sleep(100); continue; } else { // TODO: 如果重试多次复制依然失败,并且当前是 Administrator 身份,则可以考虑使用延迟复制方法,最后提醒用户重启 Windows string strText = "source '" + source + "' lastmodified = '" + File.GetLastWriteTimeUtc(source).ToString() + "'; " + "target '" + target + "' lastmodified = '" + File.GetLastWriteTimeUtc(target).ToString() + "'"; throw new Exception(strText, ex); } } Debug.Assert(File.GetLastWriteTimeUtc(source) == File.GetLastWriteTimeUtc(target), "源文件和目标文件复制完成后,最后修改时间不同"); break; } nCount++; } } catch (System.UnauthorizedAccessException ex) { strError = ExceptionUtil.GetDebugText(ex); return -2; } catch (Exception ex) { strError = ExceptionUtil.GetDebugText(ex); return -1; } return nCount; }
// TODO: 可改用 PathUtil 中同名函数 /* * Type: System.IO.IOException * Message: 文件“c:\dp2circulation\DigitalPlatform.CirculationClient.dll”正由另一进程使用,因此该进程无法访问此文件。 * Stack: * 在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) * 在 System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite) * 在 System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite) * 在 dp2Circulation.GreenProgram.CopyDirectory(String strSourceDir, String strTargetDir, FileNameFilterProc filter_proc, String& strError) * */ // 拷贝目录 // return: // -2 权限不够 // -1 出错 // >=0 复制的文件总数 public static int CopyDirectory(string strSourceDir, string strTargetDir, FileNameFilterProc filter_proc, StringBuilder debugInfo, out string strError) { strError = ""; int nCount = 0; try { DirectoryInfo di = new DirectoryInfo(strSourceDir); if (di.Exists == false) { strError = "源目录 '" + strSourceDir + "' 不存在..."; return(-1); } #if NO if (bDeleteTargetBeforeCopy == true) { if (Directory.Exists(strTargetDir) == true) { Directory.Delete(strTargetDir, true); } } #endif PathUtil.TryCreateDir(strTargetDir); FileSystemInfo[] subs = di.GetFileSystemInfos(); foreach (FileSystemInfo sub in subs) { if (filter_proc != null && filter_proc(sub) == false) { continue; } // 复制目录 if ((sub.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { int nRet = CopyDirectory(sub.FullName, Path.Combine(strTargetDir, sub.Name), filter_proc, debugInfo, out strError); if (nRet == -1) { return(-1); } if (nRet == -2) { return(-2); } nCount += nRet; continue; } // 复制文件 string source = sub.FullName; string target = Path.Combine(strTargetDir, sub.Name); // 如果目标文件已经存在,并且修后修改时间相同,则不复制了 if (File.Exists(target) == true && File.GetLastWriteTimeUtc(source) == File.GetLastWriteTimeUtc(target)) { if (debugInfo != null) { debugInfo.Append("目标文件 " + target + "已经存在,并且和源文件最后修改时间相同,被跳过\r\n"); } continue; } // 拷贝文件,最多重试 10 次 for (int nRedoCount = 0; ; nRedoCount++) { try { File.Copy(source, target, true); if (debugInfo != null) { debugInfo.Append("复制文件 " + source + " --> " + target + "\r\n"); } } catch (Exception ex) { if (nRedoCount < 10) { Thread.Sleep(100); continue; } else { // TODO: 如果重试多次复制依然失败,并且当前是 Administrator 身份,则可以考虑使用延迟复制方法,最后提醒用户重启 Windows string strText = "source '" + source + "' lastmodified = '" + File.GetLastWriteTimeUtc(source).ToString() + "'; " + "target '" + target + "' lastmodified = '" + File.GetLastWriteTimeUtc(target).ToString() + "'"; throw new Exception(strText, ex); } } Debug.Assert(File.GetLastWriteTimeUtc(source) == File.GetLastWriteTimeUtc(target), "源文件和目标文件复制完成后,最后修改时间不同"); break; } nCount++; } } catch (System.UnauthorizedAccessException ex) { strError = ExceptionUtil.GetDebugText(ex); return(-2); } catch (Exception ex) { strError = ExceptionUtil.GetDebugText(ex); return(-1); } return(nCount); }
// 拷贝目录 // return: // -1 出错 // >=0 复制的文件总数 public static int CopyDirectory(string strSourceDir, string strTargetDir, FileNameFilterProc filter_proc, out string strError) { strError = ""; int nCount = 0; try { DirectoryInfo di = new DirectoryInfo(strSourceDir); if (di.Exists == false) { strError = "源目录 '" + strSourceDir + "' 不存在..."; return(-1); } #if NO if (bDeleteTargetBeforeCopy == true) { if (Directory.Exists(strTargetDir) == true) { Directory.Delete(strTargetDir, true); } } #endif CreateDirIfNeed(strTargetDir); FileSystemInfo[] subs = di.GetFileSystemInfos(); foreach (FileSystemInfo sub in subs) { if (filter_proc != null && filter_proc(sub) == false) { continue; } // 复制目录 if ((sub.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { int nRet = CopyDirectory(sub.FullName, Path.Combine(strTargetDir, sub.Name), filter_proc, out strError); if (nRet == -1) { return(-1); } nCount += nRet; continue; } // 复制文件 string source = sub.FullName; string target = Path.Combine(strTargetDir, sub.Name); // 如果目标文件已经存在,并且修后修改时间相同,则不复制了 if (File.Exists(target) == true && File.GetLastWriteTimeUtc(source) == File.GetLastWriteTimeUtc(target)) { continue; } File.Copy(source, target, true); // 把最后修改时间设置为和 source 一样 File.SetLastWriteTimeUtc(target, File.GetLastWriteTimeUtc(source)); nCount++; } } catch (Exception ex) { strError = ex.Message; return(-1); } return(nCount); }
// 拷贝目录 // return: // -1 出错 // >=0 复制的文件总数 public static int CopyDirectory(string strSourceDir, string strTargetDir, FileNameFilterProc filter_proc, out string strError) { strError = ""; int nCount = 0; try { DirectoryInfo di = new DirectoryInfo(strSourceDir); if (di.Exists == false) { strError = "源目录 '" + strSourceDir + "' 不存在..."; return -1; } #if NO if (bDeleteTargetBeforeCopy == true) { if (Directory.Exists(strTargetDir) == true) Directory.Delete(strTargetDir, true); } #endif CreateDirIfNeed(strTargetDir); FileSystemInfo[] subs = di.GetFileSystemInfos(); foreach (FileSystemInfo sub in subs) { if (filter_proc != null && filter_proc(sub) == false) continue; // 复制目录 if ((sub.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { int nRet = CopyDirectory(sub.FullName, Path.Combine(strTargetDir, sub.Name), filter_proc, out strError); if (nRet == -1) return -1; nCount += nRet; continue; } // 复制文件 string source = sub.FullName; string target = Path.Combine(strTargetDir, sub.Name); // 如果目标文件已经存在,并且修后修改时间相同,则不复制了 if (File.Exists(target) == true && File.GetLastWriteTimeUtc(source) == File.GetLastWriteTimeUtc(target)) continue; // File.Copy(source, target, true); // 拷贝文件,最多重试 10 次 for (int nRedoCount = 0; ; nRedoCount++) { try { File.Copy(source, target, true); } catch (Exception ex) { if (nRedoCount < 10) { Thread.Sleep(100); continue; } else { string strText = "source '" + source + "' lastmodified = '" + File.GetLastWriteTimeUtc(source).ToString() + "'; " + "target '" + target + "' lastmodified = '" + File.GetLastWriteTimeUtc(target).ToString() + "'"; throw new Exception(strText, ex); } } Debug.Assert(File.GetLastWriteTimeUtc(source) == File.GetLastWriteTimeUtc(target), "源文件和目标文件复制完成后,最后修改时间不同"); break; } // 把最后修改时间设置为和 source 一样 File.SetLastWriteTimeUtc(target, File.GetLastWriteTimeUtc(source)); nCount++; } } catch (Exception ex) { strError = ex.Message; return -1; } return nCount; }