public FileData(string dir) { m_find_data = new Win32.WIN32_FIND_DATA(); using (var handle = FindFirstFile(dir, ref m_find_data)) if (handle.IsInvalid) { throw new FileNotFoundException($"Failed to get WIN32_FIND_Data for {dir}"); } FullPath = dir; }
private bool MoveToNextFile(out Win32.WIN32_FIND_DATA findData) { if (Win32.FindNextFile(FindHandle, out findData)) { return(true); } var errorCode = Marshal.GetLastWin32Error(); if (errorCode == Win32.ERROR_NO_MORE_FILES) { return(false); } throw new FileSystemException(SearchPath, Resources.Error_Failed_to_find_the_next_file + errorCode.GetExceptionMessageForCulture(Thread.CurrentThread.CurrentCulture)); }
private bool MoveToFirstFile(out Win32.WIN32_FIND_DATA findData) { FindHandle = Win32.FindFirstFile(GetPathAdaptedForSearch(SearchPath), out findData); if (FindHandle.IsValidHandle()) { return(true); } var errorCode = Marshal.GetLastWin32Error(); if (errorCode == Win32.ERROR_NO_MORE_FILES) { return(false); } throw new FileSystemException(SearchPath, errorCode.GetExceptionMessageForCulture(Thread.CurrentThread.CurrentCulture)); }
private static extern bool FindNextFile(SafeFindHandle hndFindFile, ref Win32.WIN32_FIND_DATA lpFindFileData);
private static extern SafeFindHandle FindFirstFile(string fileName, ref Win32.WIN32_FIND_DATA data);
public FileData(FileData rhs) { m_find_data = rhs.m_find_data; FullPath = rhs.FullPath; }
public FileData(string dir, ref Win32.WIN32_FIND_DATA find_data, Match?regex_match = null) { m_find_data = find_data; FullPath = Path.Combine(dir, FileName); RegexMatch = regex_match; }
public static IEnumerable <FileData> EnumFileSystem(string path, SearchOption search_flags = SearchOption.TopDirectoryOnly, string?regex_filter = null, RegexOptions regex_options = RegexOptions.IgnoreCase, FileAttributes exclude = FileAttributes.Hidden, Func <string, bool>?progress = null) { /// <remarks> /// A fast enumerator of files in a directory. /// Use this if you need to get attributes for all files in a directory. /// This enumerator is substantially faster than using <see cref="Directory.GetFiles(string)"/> /// and then creating a new FileInfo object for each path. Use this version when you /// will need to look at the attributes of each file returned (for example, you need /// to check each file in a directory to see if it was modified after a specific date). /// </remarks> Debug.Assert(Path_.DirExists(path), "Attempting to enumerate an invalid directory path"); // Default progress callback if (progress == null) { progress = s => true; } // File/Directory name filter var filter = regex_filter != null ? new Regex(regex_filter, regex_options) : null; // For drive letters, add a \, 'FileIOPermission' needs it if (path.EndsWith(":")) { path += "\\"; } // Local stack for recursion var stack = new Stack <string>(20); for (stack.Push(path); stack.Count != 0;) { // Report progress var dir = stack.Pop(); if (!progress(dir)) { break; } // Skip paths we don't have access to try { new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dir).Demand(); } catch { continue; } // Use the win32 find files var pattern = Path.Combine(dir, "*"); var find_data = new Win32.WIN32_FIND_DATA(); using (var handle = FindFirstFile(pattern, ref find_data)) { for (var more = !handle.IsInvalid; more; more = FindNextFile(handle, ref find_data)) { // Exclude files with any of the exclude attributes if ((find_data.Attributes & exclude) != 0) { continue; } // Filter if provided if (find_data.FileName != "." && find_data.FileName != "..") { Match m; if (filter == null) { yield return(new FileData(dir, ref find_data)); } else if ((m = filter.Match(find_data.FileName)).Success) { yield return(new FileData(dir, ref find_data, m)); } } // If the found object is a directory, see if we should be recursing if (search_flags == SearchOption.AllDirectories && (find_data.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { if (find_data.FileName == "." || find_data.FileName == "..") { continue; } stack.Push(Path.Combine(dir, find_data.FileName)); } } } } }