Reputation: 837
I have a "Restore" program written in C # that at one point needs to look for four particular types of files, move any of those types of files to a directory (and first create that directory if it doesn't exist), then move all instances of those types of files into the directory before writing in files from a Backup. Here is my section of code:
private void restoreFromBackup(string chosenFile)
{
this
.Cursor = Cursors.WaitCursor;
// Create new directory in which to move existing .bin and .hid files on the PC
if (!Directory.Exists("C:\\Phoenix\\OldBinHid"))
{
Directory.CreateDirectory("C:\\Phoenix\\OldBinHid");
}
else
{
Array.ForEach(Directory.GetFiles(@"C:\\Phoenix\\OldBinHid"), File.Delete);
}
// Move existing .bin and .hid files to the new directory
string pattern = @"(\.bin|\.hid|\.BIN|.HID)$";
var files = Directory.GetFiles(@"C:\Phoenix")
.Where(x => Regex.IsMatch(x, pattern))
.Select(x => x).ToList();
foreach (var item in files)
{
Console.WriteLine(item);
string name = item.Substring(item.LastIndexOf("\\") + 1);
File.Move(item, Path.Combine(@"C:\Phoenix\OldBinHid", name));
}
The Create Directory works just fine, but even though I put one example of each of the types of files (Test.bin, Test.BIN, Test.hid and Test.HID) in the C:\Phoenix directory, none of them were moved to the C:\Phoenix\OldBinHid directory. I also then put copies of simlar test files in the C:\Phoenix\OldBinHid directory and ran my Restore a 2nd time - it did not delete any files in that directory either.
What do I have wrong here?
Any help would be greatly appreciated.
Thank you
Hmmm - it is STILL not doing what I want it to do. The Restore will be for when one of our off-site locations receives a new PC that will automatically come loaded with default .bin and .hid files. But our off-site locations will more than likely have built up a number of different .bin and .hid files on their previous PC, which should have backed up the night before by zipping up certain files, to another PC, including all of their .bin and .hid files. What I need to do is have the Restore program check to see if a C:\Phoenix\OldBinHid directory already exists (which technically it shouldn't, but sometimes they have to put the old PC back in place if there are other issues with the new PC) and if it does exist, delete all the files in there. If it doesn't exist, it should create the C:\Phoenix\OldBinHid directory, then search the parent (C:\Phoenix) directory for all .bin and .hid files and move them into the \OldBinHid directory so that when the Restore unzips the Backup, it will put their most current, backed-up .bin and .hid files back in place.
I put several test files (TestA.bin, TestB.BIN, TestC.hid, TestD.HID) in my \Phoenix directory last night, so they would get backed up. I also had a few test files in the OldBinHid directory. I then first tried some of your corrections to what I had in my Restore program, Simon. Did not work - program ran, but nothing was deleted from the \OldBinHid directory and none of my test files were moved there. I then put in a few more test files, so I knew there would be extra test files in my \Phoenix directory and ran my Restore again. Still nothing moved into the Directory and original test files still in the \OldBinHid directory. So I went with your cleaner version - here is what I have:
// Create new directory in which to move existing .bin and .hid files on the PC
string sourceDirectory = @"C:\Phoenix";
string destinationDirectory = @"C:\Phoenix\OldBinHid";
string pattern = @"(\.bin|\.hid)$";
Directory.CreateDirectory(destinationDirectory);
Array.ForEach(Directory.GetFiles(destinationDirectory), File.Delete);
// Move existing .bin and .hid files to the new directory
var files = Directory.GetFiles(sourceDirectory)
.Where(x => Regex.IsMatch(x, pattern, RegexOptions.IgnoreCase))
.Select(x => x)
.ToArray();
Array.ForEach(files, file =>
{
Console.WriteLine(file);
File.Move(file, Path.Combine(destinationDirectory, Path.GetFileName(file)));
});
And still ran without any errors, but nothing got deleted or moved. Am I still missing something here?
Upvotes: 0
Views: 2105
Reputation: 5216
I've just knocked-up a console app and copied your code in. As @Zong Zheng says, you need to remove the double backslash if you're using string literals. So
@"C:\Phoenix\.."
instead of
@"C:\\Phoenix\\.."
That worked for me. Here is my code (based on yours):
class Program
{
static void Main(string[] args)
{
restoreFromBackup("");
}
private static void restoreFromBackup(string chosenFile)
{
// Create new directory in which to move existing .bin and .hid files on the PC
if (!Directory.Exists(@"G:\temp\test2\test3"))
{
Directory.CreateDirectory(@"G:\temp\test2\test3");
}
else
{
Array.ForEach(Directory.GetFiles(@"G:\temp\test2\test3"), File.Delete);
}
// Move existing .bin and .hid files to the new directory
string pattern = @"(\.bin|\.hid|\.BIN|.HID)$";
var files = Directory.GetFiles(@"G:\temp\test2")
.Where(x => Regex.IsMatch(x, pattern))
.Select(x => x).ToList();
foreach (var item in files)
{
Console.WriteLine(item);
string name = item.Substring(item.LastIndexOf("\\") + 1);
File.Move(item, Path.Combine(@"G:\temp\test2\test3", name));
}
}
}
It exhibits both behaviours - if the directory exists, it deletes anything in there. If it does not exist - it creates it.
Then it copies any files from the base directory in to the subdirectory.
However, if you mix the double backslash and string literal character @, it stops working.
Also, I'd definitely change this line:
string name = item.Substring(item.LastIndexOf("\\") + 1);
to
string name = Path.GetFilename(item);
It's cleaner and more readable and free because it's built-in.
As a further improvement, I'd consider using this overload of the Regex.IsMatch method and specifying 'IgnoreCase' in the RegexOptions param. Then, you can get rid of the .BIN/.bin combinations. This could be a source of your issue (although I've not checked) - what if the file in your folder is Something.Bin rather than Something.bin or Something.BIN? Ignoring the case will eliminate that issue.
Here is a slightly cleaner version of the same code:
private static void restoreFromBackup(string chosenFile)
{
string sourceDirectory = @"G:\temp\test2";
string destinationDirectory = @"G:\temp\test2\test3";
string pattern = @"(\.bin|\.hid)$";
// Create new directory in which to move existing .bin and .hid files on the PC
Directory.CreateDirectory(destinationDirectory);
Array.ForEach(Directory.GetFiles(destinationDirectory), File.Delete);
var files = Directory.GetFiles(sourceDirectory)
.Where(x => Regex.IsMatch(x, pattern, RegexOptions.IgnoreCase))
.Select(x => x)
.ToArray();
Array.ForEach(files, file =>
{
Console.WriteLine(file);
File.Move(file, Path.Combine(destinationDirectory, Path.GetFileName(file)));
});
}
Hope this helps you.
EDIT
Given your feedback (still not working), you need to make some mods to the program in order to do some detailed debugging.
1. Firstly, split this line
Array.ForEach(Directory.GetFiles(destinationDirectory), File.Delete);
In to two lines:
var filesToDelete = Directory.GetFiles(destinationDirectory);
Array.ForEach(filesToDelete, File.Delete);
Put a breakpoint after the var filesToDelete... line and add a watch on filesToDelete. What do you see? Are there any file names in the filesToDelete variable?
2. Put a breakpoint on the foreach (var item in files)
And add a watch on the files variable. Again, what do you see?
You need to start breaking it down to see where it fails.
At this stage, my money is now on either (lack of) permissions or incorrect paths/drive letter/wildcards. Are you sure you're looking at the right folders? Drive letters?
Things don't tend to not do anything. They either work or they produce exceptions. It's not often that 'nothing happens'. Unless you are filtering stuff out so that the loops don't actually loop.
Dust down your C# debugging skills and report back...
Also, describe the environment you are running in. Are the files on a local physical drive or across a network? What version of Windows? Is it .NET Windows or MONO? What machine are you running on? Size of files? Diskspace? etc
Upvotes: 2