public static Result CopyDirectory(this FileSystemClient fs, string sourcePath, string destPath, CreateFileOptions options = CreateFileOptions.None, IProgressReport logger = null) { Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath.ToU8Span(), OpenDirectoryMode.All); if (rc.IsFailure()) { return(rc); } try { foreach (DirectoryEntryEx entry in fs.EnumerateEntries(sourcePath, "*", SearchOptions.Default)) { string subSrcPath = PathTools.Normalize(PathTools.Combine(sourcePath, entry.Name)); string subDstPath = PathTools.Normalize(PathTools.Combine(destPath, entry.Name)); if (entry.Type == DirectoryEntryType.Directory) { fs.EnsureDirectoryExists(subDstPath); rc = fs.CopyDirectory(subSrcPath, subDstPath, options, logger); if (rc.IsFailure()) { return(rc); } } if (entry.Type == DirectoryEntryType.File) { logger?.LogMessage(subSrcPath); fs.CreateOrOverwriteFile(subDstPath, entry.Size, options); rc = fs.CopyFile(subSrcPath, subDstPath, logger); if (rc.IsFailure()) { return(rc); } } } } finally { if (sourceHandle.IsValid) { fs.CloseDirectory(sourceHandle); } } return(Result.Success); }
public static IEnumerable <DirectoryEntryEx> EnumerateEntries(this FileSystemClient fs, string path, string searchPattern, SearchOptions searchOptions) { bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive); bool recurse = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories); fs.OpenDirectory(out DirectoryHandle sourceHandle, path.ToU8Span(), OpenDirectoryMode.All).ThrowIfFailure(); try { while (true) { DirectoryEntry dirEntry = default; fs.ReadDirectory(out long entriesRead, SpanHelpers.AsSpan(ref dirEntry), sourceHandle); if (entriesRead == 0) { break; } DirectoryEntryEx entry = FileSystemExtensions.GetDirectoryEntryEx(ref dirEntry, path); if (PathTools.MatchesPattern(searchPattern, entry.Name, ignoreCase)) { yield return(entry); } if (entry.Type != DirectoryEntryType.Directory || !recurse) { continue; } IEnumerable <DirectoryEntryEx> subEntries = fs.EnumerateEntries(PathTools.Combine(path, entry.Name), searchPattern, searchOptions); foreach (DirectoryEntryEx subEntry in subEntries) { yield return(subEntry); } } } finally { if (sourceHandle.IsValid) { fs.CloseDirectory(sourceHandle); } } }