UPD: Don't calculate statistics when move directories on the same volume #2

This commit is contained in:
Alexander Koblov 2021-03-10 13:59:39 +00:00
commit 8fa99d4a71
3 changed files with 52 additions and 24 deletions

View file

@ -71,7 +71,7 @@ type
implementation
uses
fFileSystemCopyMoveOperationOptions, uGlobs, uAdministrator;
fFileSystemCopyMoveOperationOptions, uGlobs;
constructor TFileSystemMoveOperation.Create(aFileSource: IFileSource;
var theSourceFiles: TFiles;
@ -107,10 +107,8 @@ end;
procedure TFileSystemMoveOperation.Initialize;
var
ARecursive: Boolean;
TreeBuilder: TFileSystemTreeBuilder;
begin
ARecursive:= Recursive;
// Get initialized statistics; then we change only what is needed.
FStatistics := RetrieveStatistics;
@ -118,7 +116,7 @@ begin
@AskQuestion,
@CheckOperationState);
try
TreeBuilder.Recursive := ARecursive;
TreeBuilder.Recursive := Recursive;
// In move operation don't follow symlinks.
TreeBuilder.SymLinkOption := fsooslDontFollow;
TreeBuilder.SearchTemplate := Self.SearchTemplate;
@ -148,7 +146,6 @@ begin
FStatistics);
FOperationHelper.Verify := FVerify;
FOperationHelper.Recursive := ARecursive;
FOperationHelper.RenameMask := RenameMask;
FOperationHelper.ReserveSpace := FReserveSpace;
FOperationHelper.CheckFreeSpace := CheckFreeSpace;
@ -173,8 +170,6 @@ begin
end;
function TFileSystemMoveOperation.Recursive: Boolean;
var
Index: Integer;
begin
// First check that both paths on the same volume
if not mbFileSameVolume(ExcludeTrailingBackslash(SourceFiles.Path),
@ -189,14 +184,6 @@ begin
Exit(True);
end;
for Index:= 0 to SourceFiles.Count - 1 do
begin
if SourceFiles[Index].IsDirectory then
begin
if DirectoryExistsUAC(TargetPath + SourceFiles[Index].Name) then
Exit(True);
end;
end;
Result:= False;
end;

View file

@ -68,7 +68,6 @@ type
FRenamingRootDir: Boolean;
FRootDir: TFile;
FVerify,
FRecursive,
FReserveSpace,
FCheckFreeSpace: Boolean;
FSkipAllBigFiles: Boolean;
@ -146,7 +145,6 @@ type
procedure ProcessTree(aFileTree: TFileTree);
property Verify: Boolean read FVerify write FVerify;
property Recursive: Boolean read FRecursive write FRecursive;
property FileExistsOption: TFileSourceOperationOptionFileExists read FFileExistsOption write FFileExistsOption;
property DirExistsOption: TFileSourceOperationOptionDirectoryExists read FDirExistsOption write FDirExistsOption;
property CheckFreeSpace: Boolean read FCheckFreeSpace write FCheckFreeSpace;
@ -327,7 +325,7 @@ begin
// Add link to current node.
AddedIndex := CurrentNode.AddSubNode(aFile);
AddedNode := CurrentNode.SubNodes[AddedIndex];
AddedNode.Data := TFileTreeNodeData.Create;
AddedNode.Data := TFileTreeNodeData.Create(FRecursive);
(CurrentNode.Data as TFileTreeNodeData).SubnodesHaveLinks := True;
// Then add linked file/directory as a subnode of the link.
@ -393,7 +391,6 @@ begin
FBufferSize := gCopyBlockSize;
GetMem(FBuffer, FBufferSize);
FRecursive := True;
FCheckFreeSpace := True;
FSkipAllBigFiles := False;
FSkipReadError := False;
@ -1115,7 +1112,7 @@ begin
Result := True;
bRemoveDirectory := False;
end
else if FRecursive then
else if NodeData.Recursive then
begin
// Create target directory.
if CreateDirectoryUAC(AbsoluteTargetFileName) then
@ -1142,6 +1139,20 @@ begin
fsoterAddToTarget:
begin
if (FMode = fsohmMove) and (not NodeData.Recursive) then
begin
with TFileSystemTreeBuilder.Create(AskQuestion, CheckOperationState) do
try
// In move operation don't follow symlinks.
SymLinkOption := fsooslDontFollow;
BuildFromNode(aNode);
FStatistics.TotalFiles += FilesCount;
FStatistics.TotalBytes += FilesSize;
finally
Free;
end;
end;
// Don't create existing directory, but copy files into it.
Result := ProcessNode(aNode, IncludeTrailingPathDelimiter(AbsoluteTargetFileName));
end;

View file

@ -15,12 +15,18 @@ uses
type
// Additional data for the filesystem tree node.
{ TFileTreeNodeData }
TFileTreeNodeData = class
public
Recursive: Boolean;
// True if any of the subnodes (recursively) are links.
SubnodesHaveLinks: Boolean;
// Whether directory or subdirectories have any elements that will not be copied/moved.
SubnodesHaveExclusions: Boolean;
constructor Create(ARecursive: Boolean); overload;
end;
{ TFileSourceTreeBuilder }
@ -58,6 +64,7 @@ type
CheckOperationStateFunction: TCheckOperationStateFunction);
destructor Destroy; override;
procedure BuildFromNode(aNode: TFileTreeNode);
procedure BuildFromFiles(Files: TFiles);
function ReleaseTree: TFileTree;
@ -82,6 +89,13 @@ implementation
uses
uGlobs, uLng;
{ TFileTreeNodeData }
constructor TFileTreeNodeData.Create(ARecursive: Boolean);
begin
Recursive:= ARecursive;
end;
constructor TFileSourceTreeBuilder.Create(AskQuestionFunction: TAskQuestionFunction;
CheckOperationStateFunction: TCheckOperationStateFunction);
begin
@ -98,6 +112,22 @@ begin
FFilesTree.Free;
end;
procedure TFileSourceTreeBuilder.BuildFromNode(aNode: TFileTreeNode);
begin
FFilesSize := 0;
FFilesCount := 0;
FCurrentDepth := 0;
FDirectoriesCount := 0;
FFilesTree := aNode;
FRootDir := aNode.TheFile.Path;
TFileTreeNodeData(FFilesTree.Data).Recursive:= FRecursive;
AddFilesInDirectory(aNode.TheFile.FullPath + DirectorySeparator, FFilesTree);
FFilesTree := nil;
end;
procedure TFileSourceTreeBuilder.BuildFromFiles(Files: TFiles);
var
i: Integer;
@ -105,7 +135,7 @@ begin
FreeAndNil(FFilesTree);
FFilesTree := TFileTreeNode.Create;
FFilesTree.Data := TFileTreeNodeData.Create;
FFilesTree.Data := TFileTreeNodeData.Create(FRecursive);
FFilesSize := 0;
FFilesCount := 0;
FDirectoriesCount := 0;
@ -135,7 +165,7 @@ var
begin
AddedIndex := CurrentNode.AddSubNode(aFile);
AddedNode := CurrentNode.SubNodes[AddedIndex];
AddedNode.Data := TFileTreeNodeData.Create;
AddedNode.Data := TFileTreeNodeData.Create(FRecursive);
Inc(FFilesCount);
FFilesSize:= FFilesSize + aFile.Size;
@ -149,7 +179,7 @@ var
begin
AddedIndex := CurrentNode.AddSubNode(aFile);
AddedNode := CurrentNode.SubNodes[AddedIndex];
AddedNode.Data := TFileTreeNodeData.Create;
AddedNode.Data := TFileTreeNodeData.Create(FRecursive);
(CurrentNode.Data as TFileTreeNodeData).SubnodesHaveLinks := True;
@ -164,7 +194,7 @@ var
begin
AddedIndex := CurrentNode.AddSubNode(aFile);
AddedNode := CurrentNode.SubNodes[AddedIndex];
NodeData := TFileTreeNodeData.Create;
NodeData := TFileTreeNodeData.Create(FRecursive);
AddedNode.Data := NodeData;
Inc(FDirectoriesCount);