I'd like to write an archiving function that takes all files in a folder and move them into an archive sub folder using the current date. The process could be run several times in a day and therefore needs to handle duplicates.
The rules for the archiving are below:
I can do this using lots of File.Exist
and LastIndexOf
calls but is there a more elegant way? maybe with LINQ?
EDIT:
This is the code I have already. It's a bit rough and ready but it gives an idea of what I want to do.
/// <summary>
/// Move the local file into the archive location.
/// If the file already exists then add a counter to the file name or increment the existing counter
/// </summary>
/// <param name="LocalFilePath">The full path of the file to be archived</param>
/// <param name="ArchiveFilePath">The proposed full path of the file once it's been archived</param>
private void ArchiveFile(string LocalFilePath, string ArchiveFilePath)
{
// Ensure the file name doesn't already exists in the location we want to move it to
if (File.Exists(ArchiveFilePath) == true)
{
// Does the archive file have a number at the end?
string[] archiveSplit = Path.GetFileNameWithoutExtension(ArchiveFilePath).Split('_');
if( archiveSplit.Length == 1)
{
// No number detected so append the number 1 to the filename
string newArcFileName = string.Format("{0}_1.{1}",
Path.GetFileNameWithoutExtension(ArchiveFilePath), Path.GetExtension(ArchiveFilePath));
// Create the new full path
string newArcPath = Path.Combine(Path.GetDirectoryName(ArchiveFilePath), newArcFileName);
// recursively call the archive folder to ensure the new file name doesn't exist before moving
ArchiveFile( LocalFilePath, newArcPath);
}
else
{
// Get the number of the last element of the split
int lastNum = Convert.ToInt32( archiveSplit.Last().Substring(1) ) +1;
// Rebuild the filename using the incremented number
string newArcFileName = archiveSplit[0];
for (int i = 1; i < archiveSplit.Length; i++)
{
newArcFileName += archiveSplit[i];
}
// finally add the number and extension
newArcFileName = string.Format("{0}_{1}.{2}", newArcFileName, lastNum, Path.GetExtension(ArchiveFilePath));
// Create the new full path
string newArcPath = Path.Combine(Path.GetDirectoryName(ArchiveFilePath), newArcFileName);
// recursively call the archive folder to ensure the new file name doesn't exist before moving
ArchiveFile(LocalFilePath, newArcPath);
}
}
else
{
// There is no file with a matching name
File.Move(LocalFilePath, ArchiveFilePath);
}
}
The Directory
class has a method to receive a list of all files within. That method allows you to specify a filter string, like so:
Directory.GetFiles(directoryPath, filterString);
If you already know your filename prefix, you can use that filter string to get all the files within that pattern:
filterString = string.Format("{0}_*.{1}", defaultFileNameWithoutExtension, defaultExtension);
You can then simply select the one with the highest suffix, extract the suffix digits, increase it and build your new (unused) file name.
Disclaimer: This was written by heart, feel free to edit in case of errors :)
File.Exists
would still need to be called even if you use LINQ, that will not change.
I suggest keeping things simple - looping with File.Exists
and LastIndexOf
is a suitable solution, unless performance is imperative.
Maybe, you should use the "Path" API and use EndsWith instead of LastIndexOf :).
You can also have a file wich store the tree of files. (Took an eye to rsync)
Do you really want to make several duplicates of the same files even if it doesn't change ? Are you looking for an updated "modified datetime" ?
http://msdn.microsoft.com/en-us/library/system.io.path.aspx : Path
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.