My program is iterating over list of files and processing each of them using some library. It's possible that file might be corrupted in the process so I want to backup it to prevent potential corruption.
I implemented it this way:
private static void ComprocessFiles(List<string> files)
{
FileInfo file = null;
foreach (string filepath in files)
{
bool backedUp = false;
bool keepBackup = false;
try
{
file = new FileInfo(filepath);
if (!file.Exists) continue;
if (file.IsReadOnly) continue;
BackupHelper.Backup(file);
backedUp = true;
ProcessFile(file);
BackupHelper.RestoreTimestamps(file);
file.Refresh();
}
catch (Exception ex)
{
try
{
Logger.LogSkippedFile(ex.GetType().Name, ex.Message, filepath);
if (backedUp) BackupHelper.RestoreFile(file);
}
catch (Exception ex)
{
keepBackup = true;
}
// Listed exceptions are not critical.
if (!(ex is IOException || ex is UnauthorizedAccessException || ex is System.Security.SecurityException))
{
throw;
}
}
finally
{
if (!IsCorrupted(file)) keepBackup = true;
if (!keepBackup) BackupHelper.DeleteBackup(file);
}
}
}
BackupHelper
class:
static class BackupHelper
{
static private DateTime[] timestamps = new DateTime[3];
static internal void Backup(FileInfo originalFile)
{
timestamps[0] = originalFile.CreationTime;
timestamps[1] = originalFile.LastWriteTime;
timestamps[2] = originalFile.LastAccessTime;
File.Copy(originalFile.FullName, originalFile.FullName + "_backup", true);
}
static internal void Backup(string originalFile)
{
Backup(new FileInfo(originalFile));
}
static internal void RestoreFile(FileInfo originalFile)
{
File.Copy(originalFile.FullName + "_backup", originalFile.FullName, true);
}
static internal void RestoreFile(string originalFile)
{
RestoreFile(new FileInfo(originalFile));
}
static internal void RestoreTimestamps(FileInfo originalFile)
{
originalFile.CreationTime = timestamps[0];
originalFile.LastWriteTime = timestamps[1];
originalFile.LastAccessTime = timestamps[2];
}
static internal void RestoreTimestamps(string originalFile)
{
RestoreTimestamps(new FileInfo(originalFile));
}
static internal void DeleteBackup(FileInfo originalFile)
{
timestamps = new DateTime[3];
File.Delete(originalFile + "_backup");
}
static internal void DeleteBackup(string originalFile)
{
DeleteBackup(new FileInfo(originalFile));
}
}
I tried my best as I plan to publish source code online but still feel that there is room for improvement.
I guess methods ProcessFile()
and IsCorrupted()
are not important for that question as well as Logger
class.
Important note - StackOverflowException
and OutOfMemoryException
can't be thrown by this code as it don't do many method calls and don't use much memory.