protected LargeFileObject(FileSystem fileSystem, FileParameters fileParams, LargeFileSystem.ParsedPath[] relatedFiles) : base(fileSystem, fileParams) { this.LargeFileSystem = (LargeFileSystem)fileSystem; this.UnderlayFileSystem = this.LargeFileSystem.UnderlayFileSystem; this.InitialRelatedFiles = relatedFiles; }
public FileImpl(VfsRandomAccessFile file, IRandomAccess <byte> randomAccessBase, string fullPath, FileSystem fileSystem, FileParameters fileParams) : base(new ConcurrentRandomAccess <byte>(randomAccessBase), fileSystem, fileParams) { this.File = file; this.File.AddHandleRef(); try { this.FullPath = fullPath; } catch { this.File.ReleaseHandleRef(); throw; } }
public static async Task CopyFileAsync(FileSystem srcFileSystem, string srcPath, FileSystem destFileSystem, string destPath, CopyFileParams?param = null, object?state = null, CancellationToken cancel = default, RefBool?readErrorIgnored = null) { if (readErrorIgnored == null) { readErrorIgnored = new RefBool(false); } readErrorIgnored.Set(false); if (param == null) { param = new CopyFileParams(); } srcPath = await srcFileSystem.NormalizePathAsync(srcPath, cancel : cancel); destPath = await destFileSystem.NormalizePathAsync(destPath, cancel : cancel); if (srcFileSystem == destFileSystem) { if (srcFileSystem.PathParser.PathStringComparer.Equals(srcPath, destPath)) { throw new FileException(destPath, "Both source and destination is the same file."); } } using (ProgressReporterBase reporter = param.ProgressReporterFactory.CreateNewReporter($"CopyFile '{srcFileSystem.PathParser.GetFileName(srcPath)}'", state)) { using (var srcFile = await srcFileSystem.OpenAsync(srcPath, flags: param.Flags, cancel: cancel)) { try { FileMetadata srcFileMetadata = await srcFileSystem.GetFileMetadataAsync(srcPath, param.MetadataCopier.OptimizedMetadataGetFlags, cancel); bool destFileExists = await destFileSystem.IsFileExistsAsync(destPath, cancel); using (var destFile = await destFileSystem.CreateAsync(destPath, flags: param.Flags, doNotOverwrite: !param.Overwrite, cancel: cancel)) { try { reporter.ReportProgress(new ProgressData(0, srcFileMetadata.Size)); Ref <uint> srcZipCrc = new Ref <uint>(); long copiedSize = await CopyBetweenFileBaseAsync(srcFile, destFile, param, reporter, srcFileMetadata.Size, cancel, readErrorIgnored, srcZipCrc); if (param.Flags.Bit(FileFlags.CopyFile_Verify) && param.IgnoreReadError == false) { // Verify を実施する // キャッシュを無効にするため、一度ファイルを閉じて再度開く await destFile.CloseAsync(); using (var destFile2 = await destFileSystem.OpenAsync(destPath, flags: param.Flags, cancel: cancel)) { uint destZipCrc = await CalcZipCrc32HandleAsync(destFile2, param, cancel); if (srcZipCrc.Value != destZipCrc) { // なんと Verify に失敗したぞ throw new CoresException($"CopyFile_Verify error. Src file: '{srcPath}', Dest file: '{destPath}', srcCrc: {srcZipCrc.Value}, destCrc = {destZipCrc}"); } } } reporter.ReportProgress(new ProgressData(copiedSize, copiedSize, true)); await destFile.CloseAsync(); try { await destFileSystem.SetFileMetadataAsync(destPath, param.MetadataCopier.Copy(srcFileMetadata), cancel); } catch (Exception ex) { Con.WriteDebug($"CopyFileAsync: '{destPath}': SetFileMetadataAsync failed. Error: {ex.Message}"); } } catch { if (destFileExists == false) { try { await destFile.CloseAsync(); } catch { } try { await destFileSystem.DeleteFileAsync(destPath); } catch { } } throw; } finally { await destFile.CloseAsync(); } } } finally { await srcFile.CloseAsync(); } } } }
public static void CopyFile(FileSystem srcFileSystem, string srcPath, FileSystem destFileSystem, string destPath, CopyFileParams?param = null, object?state = null, CancellationToken cancel = default, RefBool?readErrorIgnored = null) => CopyFileAsync(srcFileSystem, srcPath, destFileSystem, destPath, param, state, cancel, readErrorIgnored)._GetResult();
public static async Task <CopyDirectoryStatus> CopyDirAsync(FileSystem srcFileSystem, string srcPath, FileSystem destFileSystem, string destPath, CopyDirectoryParams?param = null, object?state = null, CopyDirectoryStatus?statusObject = null, CancellationToken cancel = default) { CopyDirectoryStatus status = statusObject ?? new CopyDirectoryStatus(); status.Clear(); status.State = state; status.StartTick = Tick64.Now; if (param == null) { param = new CopyDirectoryParams(); } srcPath = await srcFileSystem.NormalizePathAsync(srcPath, cancel : cancel); destPath = await destFileSystem.NormalizePathAsync(destPath, cancel : cancel); if (srcFileSystem == destFileSystem) { if (srcFileSystem.PathParser.PathStringComparer.Equals(srcPath, destPath)) { throw new FileException(destPath, "Both source and destination is the same directory."); } } using (ProgressReporterBase dirReporter = param.EntireProgressReporterFactory.CreateNewReporter($"CopyDir '{srcFileSystem.PathParser.GetFileName(srcPath)}'", state)) { DirectoryWalker walker = new DirectoryWalker(srcFileSystem); bool walkRet = await walker.WalkDirectoryAsync(srcPath, async (dirInfo, entries, c) => { c.ThrowIfCancellationRequested(); foreach (FileSystemEntity entity in entries) { c.ThrowIfCancellationRequested(); try { if (await param.ProgressCallbackProc(status, entity) == false) { throw new OperationCanceledException($"Copying of the file '{entity.FullPath}' is cancaled by the user."); } string entryName = entity.Name; if (entity.IsCurrentDirectory) { entryName = ""; } string srcFullPath = srcFileSystem.PathParser.Combine(srcPath, dirInfo.RelativePath, entryName); string destFullPath = destFileSystem.PathParser.Combine(destPath, srcFileSystem.PathParser.ConvertDirectorySeparatorToOtherSystem(dirInfo.RelativePath, destFileSystem.PathParser), entryName); if (entity.IsDirectory == false) { // Copy a file lock (status.LockObj) status.NumFilesTotal++; FileMetadataGetFlags metadataGetFlags = FileMetadataCopier.CalcOptimizedMetadataGetFlags(param.FileMetadataCopier.Mode | FileMetadataCopyMode.Attributes); FileMetadata srcFileMetadata = await srcFileSystem.GetFileMetadataAsync(srcFullPath, metadataGetFlags, cancel); FileFlags copyFileAdditionalFlags = FileFlags.None; lock (status.LockObj) status.SizeTotal += srcFileMetadata.Size; if (param.CopyDirFlags.Bit(CopyDirectoryFlags.CopyFileCompressionFlag)) { if (srcFileMetadata.Attributes is FileAttributes attr) { if (attr.Bit(FileAttributes.Compressed)) { copyFileAdditionalFlags |= FileFlags.OnCreateSetCompressionFlag; } else { copyFileAdditionalFlags |= FileFlags.OnCreateRemoveCompressionFlag; } } } if (param.CopyDirFlags.Bit(CopyDirectoryFlags.CopyFileSparseFlag)) { if (srcFileMetadata.Attributes is FileAttributes attr) { if (attr.Bit(FileAttributes.SparseFile)) { copyFileAdditionalFlags |= FileFlags.SparseFile; } } } var copyFileParam = param.GenerateCopyFileParams(copyFileAdditionalFlags); RefBool ignoredReadError = new RefBool(false); await CopyFileAsync(srcFileSystem, srcFullPath, destFileSystem, destFullPath, copyFileParam, state, cancel, ignoredReadError); lock (status.LockObj) { status.NumFilesOk++; status.SizeOk += srcFileMetadata.Size; if (ignoredReadError) { status.IgnoreReadErrorFileNameList.Add(srcFullPath); } } } else { // Make a directory lock (status.LockObj) { status.NumDirectoriesTotal++; } FileMetadataGetFlags metadataGetFlags = FileMetadataCopier.CalcOptimizedMetadataGetFlags(param.DirectoryMetadataCopier.Mode | FileMetadataCopyMode.Attributes); FileMetadata srcDirMetadata = await srcFileSystem.GetDirectoryMetadataAsync(srcFullPath, metadataGetFlags, cancel); FileFlags copyDirFlags = FileFlags.None; if (param.CopyDirFlags.Bit(CopyDirectoryFlags.BackupMode)) { copyDirFlags |= FileFlags.BackupMode; } if (param.CopyDirFlags.Bit(CopyDirectoryFlags.CopyDirectoryCompressionFlag)) { if (srcDirMetadata.Attributes is FileAttributes attr) { if (attr.Bit(FileAttributes.Compressed)) { copyDirFlags |= FileFlags.OnCreateSetCompressionFlag; } else { copyDirFlags |= FileFlags.OnCreateRemoveCompressionFlag; } } } await destFileSystem.CreateDirectoryAsync(destFullPath, copyDirFlags, cancel); FileMetadata dstDirMetadata = param.DirectoryMetadataCopier.Copy(srcDirMetadata); if (param.CopyDirFlags.Bit(CopyDirectoryFlags.SetAclProtectionFlagOnRootDir)) { if (dirInfo.IsRoot) { if (dstDirMetadata.Security != null) { if (dstDirMetadata.Security.Acl != null) { dstDirMetadata.Security.Acl.Win32AclSddl = "!" + dstDirMetadata.Security.Acl.Win32AclSddl; } if (dstDirMetadata.Security.Audit != null) { dstDirMetadata.Security.Audit.Win32AuditSddl = "!" + dstDirMetadata.Security.Audit.Win32AuditSddl; } } } } await destFileSystem.SetDirectoryMetadataAsync(destFullPath, dstDirMetadata, cancel); lock (status.LockObj) status.NumDirectoriesOk++; } } catch (Exception ex) { if (await param.ExceptionCallbackProc(status, entity, ex) == false) { throw ex; } } } return(true); }, async (dirInfo, entries, c) => { c.ThrowIfCancellationRequested(); foreach (FileSystemEntity entity in entries) { c.ThrowIfCancellationRequested(); string entryName = entity.Name; if (entity.IsCurrentDirectory) { entryName = ""; } string srcFullPath = srcFileSystem.PathParser.Combine(srcPath, dirInfo.RelativePath, entryName); string destFullPath = destFileSystem.PathParser.Combine(destPath, srcFileSystem.PathParser.ConvertDirectorySeparatorToOtherSystem(dirInfo.RelativePath, destFileSystem.PathParser), entryName); if (entity.IsDirectory) { // Update the directory LastWriteTime metadata after placing all inside files into the directory if (param.DirectoryMetadataCopier.Mode.BitAny(FileMetadataCopyMode.TimeAll)) { FileMetadataGetFlags metadataGetFlags = FileMetadataCopier.CalcOptimizedMetadataGetFlags(param.DirectoryMetadataCopier.Mode & (FileMetadataCopyMode.TimeAll)); FileMetadata srcDirMetadata = await srcFileSystem.GetDirectoryMetadataAsync(srcFullPath, metadataGetFlags, cancel); FileMetadata dstDirMetadata = param.DirectoryMetadataCopier.Copy(srcDirMetadata); await destFileSystem.SetDirectoryMetadataAsync(destFullPath, dstDirMetadata, cancel); } } } return(true); }, async (dirInfo, exception, c) => { c.ThrowIfCancellationRequested(); if (await param.ExceptionCallbackProc(status, dirInfo.Entity, exception) == false) { throw exception; } return(true); }, param.CopyDirFlags.Bit(CopyDirectoryFlags.Recursive), cancel ); } status.EndTick = Tick64.Now; return(status); }