Sorting files with the same first 3 letters, than deleting the older files?
I had a question last week, and you quickly alleviated any concern that it wo开发者_Python百科uld roadblock me, hoping that you can help a beginner program once more!
I'm trying to automate one of my daily mundane tasks and it's being quite a bugger, I think mainly because I'm not taking the correct approach.
Each morning I go through a system directory that houses many files with the same prefix, and a generated number following it. I have to sort alphabetically first, then remove the oldest versions of that file.
Here's an example pic of my directory: http://i.imgur.com/5l2Am.png
I was going to approach this situation by just sorting the files by name and comparing the first 3 letters to the following file, and if they were identical I would delete (or move to a backup folder) the second file, until they didn't match any longer, and I would move onto the next prefix as the comparator.
The problem with this though I found, is that they aren't always sorted correctly, and I risk deleting the wrong files.
Has anyone had experience with something of this nature? In my head and on VS I can put the pieces all there, but just can't seem to link it together, mainly because I've never ventured into the system.IO class before, but I want to learn!
Any advice is appreciated, and if you want to see my futile attempts I'll gladly share them :P.
Thanks, Nick
You should be able to use Directory.GetFiles to retrieve the filenames. I suspect that your sorting problem is probably due to casing - in C#, string sorts, by default, as case sensitive, but the file system is not.
I'd recommend loading up the list of files, then sorting them yourself, in C#, prior to processing them:
List<string> files = Directory.GetFiles(myDirectory)
.Select(file => file.ToLower()) // To lower case
.OrderBy(file => file) // Sort the files
.ToList();
// Process the files here...
Create a dictionary indexed by the three character prefix.
When you reach a file, check the dictionary for a value:
if none exists, keep the file and add it to the dictionary, where the key is the prefix and the value is the number following the prefix
if one exists, but has an older "number" value, archive the old one, keep the newer one and update the dictionary to have the new number
if one exists, but has a newer "number" value, archive the old one, keep the newer one and the dictionary is already up to date at this point.
No sorting necessary.
EDIT: Adding example:
public static void ProcessDirectory(string directoryPath)
{
IDictionary<string,string> prefixDictionary = new Dictionary<string, string>();
if (Directory.Exists(directoryPath))
{
foreach(string filePath in Directory.GetFiles(directoryPath))
{
string fileName = Path.GetFileName(filePath);
string fileDirectory = Path.GetDirectoryName(filePath);
if (fileName.Length>=3)
{
string prefix = fileName.Substring(0, 3);
string rightPart = fileName.Substring(3, fileName.Length - 3);
if (!prefixDictionary.ContainsKey(prefix))
{
prefixDictionary[prefix] = rightPart;
}
else
{
string fileToArchive = null;
string storedRightPart = prefixDictionary[prefix];
// using string compare, but you could test file date or
// or parse the right part as a number if you only cared about
// files with numbers on the right.
if (String.Compare(storedRightPart,rightPart)<0)
{
prefixDictionary[prefix] = rightPart;
fileToArchive = Path.Combine(fileDirectory,prefix+storedRightPart);
}
else
{
fileToArchive = filePath;
}
if (fileToArchive != null)
{
// perform the archive here
}
}
}
}
}
}
You get get an array of FileInfo objects, which contain a lot of the metadata about the files, which would let you sort them. It also allows you to delete.
DirectoryInfo dir = new DirectoryInfo(@"C:/yourPath");
FileInfo[] files = dir.GetFiles();
From there, you can sort files
by CreationTime
or Name
or whatever. To delete one, just use the Delete
method on the FileInfo class.
精彩评论