Skip to content

Commit 16ce2d3

Browse files
author
LoneWandererProductions
committed
lightly rework File copy
1 parent 4e0894a commit 16ce2d3

1 file changed

Lines changed: 134 additions & 144 deletions

File tree

FileHandler/FileHandleCopy.cs

Lines changed: 134 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -37,41 +37,21 @@ public static bool CopyFiles(string source, string target, bool overwrite = true
3737
{
3838
FileHandlerProcessing.ValidatePaths(source, target);
3939

40+
source = Path.GetFullPath(source);
41+
target = Path.GetFullPath(target);
42+
4043
if (!Directory.Exists(source))
41-
{
4244
return false;
43-
}
4445

45-
var sourceDir = new DirectoryInfo(source);
46-
var targetDir = new DirectoryInfo(target);
47-
if (!targetDir.Exists)
48-
{
49-
targetDir.Create();
50-
}
51-
52-
var files = sourceDir.GetFiles();
53-
foreach (var file in files)
54-
{
55-
try
56-
{
57-
file.CopyTo(Path.Combine(target, file.Name), overwrite);
58-
FileHandlerRegister.SendStatus?.Invoke(nameof(CopyFiles), file.Name);
59-
}
60-
catch (Exception ex) when (ex is UnauthorizedAccessException or ArgumentException or IOException
61-
or NotSupportedException)
62-
{
63-
FileHandlerRegister.AddError(nameof(CopyFiles), file.Name, ex);
64-
Trace.WriteLine(ex);
65-
return false;
66-
}
67-
}
46+
var srcDir = new DirectoryInfo(source);
47+
var tgtDir = new DirectoryInfo(target);
6848

69-
foreach (var subDir in sourceDir.GetDirectories())
70-
{
71-
CopyFiles(subDir.FullName, Path.Combine(target, subDir.Name), overwrite);
72-
}
49+
if (!tgtDir.Exists)
50+
tgtDir.Create();
7351

74-
return true;
52+
bool success = true;
53+
CopyDirectoryRecursive(srcDir, tgtDir, overwrite, ref success);
54+
return success;
7555
}
7656

7757
/// <summary>
@@ -85,69 +65,42 @@ public static bool CopyFiles(string source, string target, bool overwrite = true
8565
public static bool CopyFiles(List<string> source, string target, bool overwrite = true)
8666
{
8767
if (source == null || source.Count == 0 || string.IsNullOrEmpty(target))
88-
{
8968
throw new FileHandlerException(FileHandlerResources.ErrorEmptyString);
90-
}
9169

70+
// Normalize paths
71+
target = Path.GetFullPath(target);
9272
if (!Directory.Exists(target))
93-
{
94-
_ = Directory.CreateDirectory(target);
95-
}
73+
Directory.CreateDirectory(target);
9674

97-
var check = true;
98-
99-
//Give the User Optional Infos about the Amount we Copy
100-
var itm = new FileItems
101-
{
102-
Elements = new List<string>(source), Message = FileHandlerResources.InformationFileDeletion
103-
};
75+
// Overview event
76+
var overview = new FileItems { Elements = new List<string>(source), Message = FileHandlerResources.InformationFileDeletion };
77+
FileHandlerRegister.SendOverview?.Invoke(nameof(CopyFiles), overview);
10478

105-
FileHandlerRegister.SendOverview?.Invoke(nameof(CopyFiles), itm);
106-
107-
//Do the work
79+
// Determine root directory automatically
10880
var root = FileHandlerProcessing.SearchRoot(source);
109-
var file = new FileInfo(root);
110-
root = file.Directory.FullName;
81+
root = Path.GetFullPath(new FileInfo(root).Directory!.FullName);
11182

112-
foreach (var element in source)
113-
{
114-
try
115-
{
116-
file = new FileInfo(element);
83+
bool success = true;
11784

118-
var directoryPath = file.Directory.FullName;
119-
120-
//Get Sub Folder
121-
var path = FileHandlerProcessing.GetSubFolder(directoryPath, root, target);
122-
123-
if (path?.Length == 0)
124-
{
125-
continue;
126-
}
127-
128-
var tempPath = Path.Combine(path!, file.Name);
85+
foreach (var filePath in source)
86+
{
87+
var file = new FileInfo(filePath);
88+
var relative = Path.GetRelativePath(root, file.Directory!.FullName);
89+
var destDir = Path.Combine(target, relative);
12990

130-
if (!Directory.Exists(path))
131-
{
132-
_ = Directory.CreateDirectory(path);
133-
}
91+
if (!Directory.Exists(destDir))
92+
Directory.CreateDirectory(destDir);
13493

135-
_ = file.CopyTo(tempPath, overwrite);
94+
var dest = Path.Combine(destDir, file.Name);
13695

137-
FileHandlerRegister.SendStatus?.Invoke(nameof(CopyFiles), file.Name);
138-
}
139-
catch (Exception ex) when (ex is UnauthorizedAccessException or ArgumentException or IOException
140-
or NotSupportedException)
141-
{
142-
check = false;
143-
FileHandlerRegister.AddError(nameof(CopyFiles), element, ex);
144-
Trace.WriteLine(ex);
145-
}
96+
if (!TryCopyFile(file, dest, overwrite))
97+
success = false;
14698
}
14799

148-
return check;
100+
return success;
149101
}
150102

103+
151104
/// <summary>
152105
/// Copies all Files to another Location, includes subdirectories, does not Replace the files but returns a List of
153106
/// Files that might be overwritten.
@@ -160,43 +113,29 @@ public static bool CopyFiles(List<string> source, string target, bool overwrite
160113
{
161114
FileHandlerProcessing.ValidatePaths(source, target);
162115

163-
//if nothing exists we can return anyways
116+
source = Path.GetFullPath(source);
117+
target = Path.GetFullPath(target);
118+
164119
if (!Directory.Exists(source))
165-
{
166120
return null;
167-
}
168-
169-
var sourceFiles = FileHandlerProcessing.GetFilesByExtension(source, FileHandlerResources.AllFiles,
170-
FileHandlerResources.SubFolders);
171121

122+
var sourceFiles = FileHandlerProcessing.GetFilesByExtension(source, FileHandlerResources.AllFiles, FileHandlerResources.SubFolders);
172123
if (sourceFiles == null)
173-
{
174124
return null;
175-
}
176-
177-
var targetFiles = FileHandlerProcessing.GetFilesByExtension(target, FileHandlerResources.AllFiles,
178-
FileHandlerResources.SubFolders);
179125

126+
var targetFiles = FileHandlerProcessing.GetFilesByExtension(target, FileHandlerResources.AllFiles, FileHandlerResources.SubFolders);
180127
if (targetFiles == null)
181-
{
182128
return null;
183-
}
184129

185-
//Handle the diff
186-
var intersect = sourceFiles.Select(i => i).Intersect(targetFiles).ToList();
130+
var intersect = sourceFiles.Intersect(targetFiles).ToList();
187131
var except = sourceFiles.Except(targetFiles).ToList();
188132

189133
if (intersect.Count == 0)
190-
{
191134
return except.Count == 0 ? null : except;
192-
}
193135

194-
var check = CopyFiles(intersect, target, false);
195-
196-
if (!check)
197-
{
136+
// Perform copy without overwrite
137+
if (!CopyFiles(intersect, target, false))
198138
return null;
199-
}
200139

201140
return except.Count == 0 ? null : except;
202141
}
@@ -212,76 +151,127 @@ public static bool CopyFilesReplaceIfNewer(string source, string target)
212151
{
213152
FileHandlerProcessing.ValidatePaths(source, target);
214153

215-
//if nothing exists we can return anyways
154+
source = Path.GetFullPath(source);
155+
target = Path.GetFullPath(target);
156+
216157
if (!Directory.Exists(source))
217-
{
218158
return false;
219-
}
220159

221-
var check = true;
160+
bool success = true;
161+
222162
var dir = new DirectoryInfo(source);
223-
var dirs = dir.GetDirectories();
224163
var files = dir.GetFiles();
225164

226-
//Give the User Optional Infos about the Amount we Copy
227-
var lstFiles = (from file in files
228-
select file.Name).ToList();
229-
230-
var itm = new FileItems
165+
// Overview callback
166+
var overview = new FileItems
231167
{
232-
Elements = new List<string>(lstFiles), Message = FileHandlerResources.InformationFileDeletion
168+
Elements = files.Select(f => f.Name).ToList(),
169+
Message = FileHandlerResources.InformationFileDeletion
233170
};
171+
FileHandlerRegister.SendOverview?.Invoke(nameof(CopyFiles), overview);
234172

235-
FileHandlerRegister.SendOverview?.Invoke(nameof(CopyFiles), itm);
236-
237-
//do the actual work
173+
if (!Directory.Exists(target))
174+
Directory.CreateDirectory(target);
238175

239-
if (files.Length > 0)
176+
foreach (var file in files)
240177
{
241-
if (!Directory.Exists(target))
242-
{
243-
_ = Directory.CreateDirectory(target);
244-
}
178+
var dest = Path.Combine(target, file.Name);
245179

246-
foreach (var file in files)
180+
// Replace only if newer
181+
try
247182
{
248-
var tempPath = Path.Combine(target, file.Name);
249-
250-
try
183+
if (File.Exists(dest))
251184
{
252-
if (File.Exists(tempPath) && file.LastWriteTime > File.GetLastWriteTime(tempPath))
253-
{
254-
_ = file.CopyTo(tempPath, FileHandlerResources.FileOverwrite);
255-
FileHandlerRegister.SendStatus?.Invoke(nameof(CopyFiles), file.Name);
256-
}
257-
}
258-
catch (Exception ex) when (ex is UnauthorizedAccessException or ArgumentException or IOException
259-
or NotSupportedException)
260-
{
261-
check = false;
262-
FileHandlerRegister.AddError(nameof(CopyFiles), file.Name, ex);
263-
Trace.WriteLine(ex);
185+
var destTime = File.GetLastWriteTime(dest);
186+
if (file.LastWriteTime <= destTime)
187+
continue;
264188
}
189+
190+
if (!TryCopyFile(file, dest, true))
191+
success = false;
192+
}
193+
catch (Exception ex)
194+
{
195+
FileHandlerRegister.AddError(nameof(CopyFilesReplaceIfNewer), file.FullName, ex);
196+
Trace.WriteLine(ex);
197+
success = false;
265198
}
266199
}
267200

268-
if (!Directory.Exists(target))
201+
// Recurse into subdirs
202+
foreach (var sub in dir.GetDirectories())
269203
{
270-
_ = Directory.CreateDirectory(target);
204+
var newTarget = Path.Combine(target, sub.Name);
205+
if (!CopyFilesReplaceIfNewer(sub.FullName, newTarget))
206+
success = false;
271207
}
272208

273-
foreach (var subDir in dirs)
274-
{
275-
var tempPath = Path.Combine(target, subDir.Name);
209+
return success;
210+
}
276211

277-
if (File.Exists(tempPath))
212+
/// <summary>
213+
/// Copies the directory recursive.
214+
/// </summary>
215+
/// <param name="source">The source.</param>
216+
/// <param name="target">The target.</param>
217+
/// <param name="overwrite">if set to <c>true</c> [overwrite].</param>
218+
/// <param name="success">if set to <c>true</c> [success].</param>
219+
/// <returns>Success Status per operation.</returns>
220+
private static void CopyDirectoryRecursive(
221+
DirectoryInfo source,
222+
DirectoryInfo target,
223+
bool overwrite,
224+
ref bool success)
225+
{
226+
// Copy files in this directory
227+
foreach (var file in source.GetFiles())
228+
{
229+
try
278230
{
279-
continue;
231+
var dest = Path.Combine(target.FullName, file.Name);
232+
file.CopyTo(dest, overwrite);
233+
FileHandlerRegister.SendStatus?.Invoke(nameof(CopyFiles), file.Name);
234+
}
235+
catch (Exception ex) when (ex is UnauthorizedAccessException or ArgumentException or IOException or NotSupportedException)
236+
{
237+
success = false;
238+
FileHandlerRegister.AddError(nameof(CopyFiles), file.Name, ex);
239+
Trace.WriteLine(ex);
280240
}
241+
}
281242

282-
_ = CopyFiles(subDir.FullName, tempPath, FileHandlerResources.FileOverwrite);
243+
// Recurse subdirectories
244+
foreach (var subDir in source.GetDirectories())
245+
{
246+
var newTarget = new DirectoryInfo(Path.Combine(target.FullName, subDir.Name));
247+
if (!newTarget.Exists)
248+
newTarget.Create();
249+
250+
CopyDirectoryRecursive(subDir, newTarget, overwrite, ref success);
283251
}
252+
}
284253

285-
return check;
254+
/// <summary>
255+
/// Tries the copy file.
256+
/// </summary>
257+
/// <param name="file">The file.</param>
258+
/// <param name="destination">The destination.</param>
259+
/// <param name="overwrite">if set to <c>true</c> [overwrite].</param>
260+
/// <returns>Status of copy process.</returns>
261+
private static bool TryCopyFile(FileInfo file, string destination, bool overwrite)
262+
{
263+
try
264+
{
265+
file.CopyTo(destination, overwrite);
266+
FileHandlerRegister.SendStatus?.Invoke(nameof(CopyFiles), file.Name);
267+
return true;
268+
}
269+
catch (Exception ex) when (ex is UnauthorizedAccessException or ArgumentException or IOException or NotSupportedException)
270+
{
271+
FileHandlerRegister.AddError(nameof(CopyFiles), file.FullName, ex);
272+
Trace.WriteLine(ex);
273+
return false;
274+
}
286275
}
276+
287277
}

0 commit comments

Comments
 (0)