Difference between File.Copy and File.Move - c#

Nowadays I am dealing with a small application which updates the mssql's compact database files on an iss server.
I've preferred to use SSIS to organize the flow. For couple of days it worked well, but then started to give errors.
In SSIS I've used the "File System Task"s "Move File" operation to move generated files from a folder to iss server's shared folder. If it fails, in case of a locked file, it tries it later. But I've seen that sometimes the files in the destination folder started to disappear.
Then I've decided to write custom code. I've removed the "File System Task" and put a "Script Task" instead of it. And write a couple of lines in it.
string destinationFile, sourceFile;
destinationFile = Path.Combine(Dts.Variables["FileRemoteCopyLocation"].Value.ToString(), Dts.Variables["CreatedFileName"].Value.ToString());
sourceFile = Path.Combine(Dts.Variables["OrginalFilePath"].Value.ToString(), Dts.Variables["CreatedFileName"].Value.ToString());
bool written = false;
try
{
File.Copy(sourceFile, destinationFile, true);
File.Delete(sourceFile);
written = true;
}
catch(IOException) {
//log it
}
if (written)
Dts.TaskResult = (int)ScriptResults.Success;
else
Dts.TaskResult = (int)ScriptResults.Failure;
It worked well. But I tried it by locking the destination file. I've connected the destination file in Sql Server Management Studio (it is an sdf file). And surprizingly it works too.
And I've tried it from operating system, by copying the source file and pasting it to the destination. Windows 7 asks me if I want to overwrite it and I say yes and it overwrote the file (copy and replace) I use with another process, no warning no error.
But if try to rename or delete it does not let me to do that. Or if I try to cut and paste it (Move and Replace) it says "you need permission to do this action".
As I understood, "Copy, delete" and "Move" are totally different things. And I still can not understand how can I overwrite a locked file.
Any ideas?

File.Move method can be used to move the file from one path to another. This method works across disk volumes, and it does not throw an exception if the source and destination are the same.
You cannot use the Move method to overwrite an existing file. If you attempt to replace a file by moving a file of the same name into that directory, you get an IOException. To overcome this you can use the combination of Copy and Delete methods
Answer orignal from : Difference between in doing file copy/delete and Move

Although the subject is not new, I would like to share my experience. I had to change the pdf file names in my digital library. When I copied about 10,000 legal articles to another folder by changing their names using the File.Copy() method, half of it took about 15 minutes, and I stopped the process because of it takes so long. Then when I tried the same thing with the File.Move() method, the result was incredible for me: It took less than 1 minute to move the whole thing. Of course, I don't need to say that all these are directly related to the system features.

Related

FolderWatcher.Created fires, but file doesn't exist- NAS

I'm facing a very weird problem.
I have a C# project with a FolderWatcher.OnCreate on a specific LAN path.
FolderWatcher.Created += new FileSystemEventHandler(FSW_Created);
I'm working simultaneously with two systems on the NAS so when one system finishes to work - it "tells" the other by copying a file (File.Copy) to some location.
The second system is listening to that location (don't ask why that's the way of implementing that...it's a long story)
When the copy of the original file is created - the second system searches for the original copy.
This works for all these file, except of sometimes when I get a message that the original's directory doesn't exist...
I see the directory is correct, and it happens only for a few such files. It has to exist (and it actually exists) because the copy came from there....
If anyone has a clue - I'll be glad.
when the error happens I enter into the following code line:
if (!Directory.Exists(directoryPath))
Currently I just added a path - try 50 times, every second, until you find it... I can't check it now, but I guess it will work
Thanks

How to debug an issue deleting a directory using File.Delete and Directory.Delete

This one is proving very difficult to debug. Lets start with my situation:
I have an ASP.Net MVC3 web app developed with C# using .Net 4. Part of the system allows a user to upload a zip file. This is done fine, and the zip file is saved. There is also a Windows service which will periodically look for new zip files, extract them, do some work and then re-zip them back up. (I use System.IO.Compression for the zipping stuff). This part all works fine, after the processing I end up with a structure something like.
Object1Folder
\_ Input.zip
\_ ExtractedFolder
\_ Output.zip
There is also a feature that allows the user to delete the item, and the requirement is to delete the object folder, in this case "Object1Folder". Because I need to delete all sub folders and files I have the following recursive function to do the work...
public static void DeleteDirectory(string directoryPath)
{
string[] files = Directory.GetFiles(directoryPath);
string[] directories = Directory.GetDirectories(directoryPath);
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
foreach (string directory in directories)
{
DeleteDirectory(directory);
}
Directory.Delete(directoryPath, true);
}
Which is initially called something like...
DeleteDirectory("C:\\Objects\\Object1Folder");
But it doesn't work! Firstly, there is no error thrown, the code appears to successfully execute, which is annoying. But the result is that only the "Input.zip" file is removed. The "ExtractedFolder" and "Output.zip" file remains.
As far as I can tell, the code is sound. I can't see that it is a case that it doesn't attempt to delete the remaining file and folder. Unfortuantely, we don't have VS installed on the target server so I cannot step through the code and check that it attempts to delete them. Please point out if you can see this being a potential issue though?
My best guesses so far is that it is a permissions issue of some sort. What is interesting (perhaps) is that when I go to manual clean-up the problem (i.e. windows explorer delete of the "Object1Folder" it says "Denied" and asks me to confirm with the admin rights button thing that it does.
I know it's hard for you all to work the problem out, but I am looking for things that I should check to try and solve this problem. What kind of things should I ensure have correct permissions? What permissions do they need? Is there a good way for me to debug this issue? If something else has a hold of those files (maybe from the extraction process of the Windows Service), how can I check if this is the problem?
Some information about that server that might help: It's running "Windows Server 2008 R2 Datacenter" with service pack 1 and is 64-bit. The web app is assigned a user that is a member of both "Users" and "IIS_IUSRS".
Let me know if any of you need some extra information.
Have a look at the eventlog on the server; you might find an exception\error message there.
You could consider using Directory.Delete(path, true) so you delete the folder and all its content in one call (unless I do not understand your code correctly).
Have a look at files being in use. If a file is in use, the OS can't delete it. So make sure you are releasing all files correctly.
Finally, you can't force the files to be not in use so you might end up writing a clean script that runs every night to delete unwanted files and folders.
You really should use a temp destination folder for your unpacked files.
When they have been used you can try deleting them and if that fails just leave them.
The permission to write to a non-temp folder should not really be given to a presentation app residing in the iis.

How can I delete a file that is in use by another process?

When I try to delete a file occurs the following exception:
The process cannot access the file ''
because it is being used by another
process.
My code looks like:
string[] files = Directory.GetFiles(#"C:\SEDocumentConverter\SOURCE");
foreach (string file in files)
{
File.Delete(file);
}
How can I solve this problem?
There is no way to delete a file that's currently being used by another process. You have to close whatever program has that file open first, before you can delete it.
If you don't already know which program that is, you can figure it out using Handle or Process Explorer.
You can P/Invoke the Windows MoveFileEx function, and use the MOVEFILE_DELAY_UNTIL_REBOOT flag, with a NULL destination name. This will delete the file when you reboot.
If the file is being used you're out of luck in trying to delete it. I can't tell you based on your code what process might be using the file(s), but try looking here or here or here, or at any of the other questions that show up as related to this one for guidance regarding this issue, and by all means follow the guidance from #Cody Gray about using Process Explorer.
slightly off topic: But it seems from your code that you are trying to delete all files of your folder.
Well instead of deleting them one by one we have another method Directory.Delete(path, True) which will delete the directory as contained in the string named path. Then you may recreate the directory if you want. But your problem may persist here too.
Another way is to find all open handles to the file and close them forcibly.
Works nice for you, bad for any apps which were using the file.
Could try that in UI with SysInternals ProcessExplorer.
Just rename this file. This will do the thing for whoever tries to write to that location.
Notes:
1) Of course the file is not deleted physically yet. Nice to do the MoveFileEx trick mentioned here around to complete the job.
2) If you want to delete a locked file to write smth new in its place (e.g. during build), just rename the file to a GUID name. If you need the folder to be clean, either use an ignored extension / hidden attribute, or rename the file to a path under %TEMP% (if on the same drive).
3) Not all locked files can be renamed, but it works for me for like 90% practical applications. You can move a file without affecting an open read/write/execute handle, it will continue working with the moved file just good (if moved within the same NTFS volume of course).
4) That's what Windows Installer would basically do before it asks you to please reboot somewhen soon: move the file away from your eyes, schedule to be removed upon reboot. Usually the newly-installed app can be used right away.
Practical Use:
My favorite is with MSBuild. Overriding the <Copy/> task with this stuff makes all the build go linux-way. You don't care if a prev version is still running somewhere, can still build&run. The old app keeps using the old version of the files. The new app loads the newly-written version.
Might be moving to %TEMP% if on the same drive (not my case though). I'd just rename them to an extension which is ignored with the current source control client.

C# Cutting Files and Pasting in New Directory

I am trying to cut files from one directory on my computer and paste it into a new directory every time a file is created in this specific directory. I am already watching the directory would it be something simple like
if (e.ChangeType == System.IO.WatcherChangeTypes.Created)
{
//cut file
//paste into new directory
}
indeed, cut + paste is equivalent to move, so System.IO.File.MoveTo() should handle your problem quite well
First a clarification, "cut and paste" are user interface terms. In the file system, it's referred to as "moving" the file.
Second, the suggestions to use File.MoveTo may not work as you would like. The IO Watcher will tell you when a file is first created, not when it is done being written to. If you immediately move a file, you may yank it out from underneath the writer. This could result in an error in the program which is writing to the file.
The correct way to do what you are proposing is to wait until the file has been closed by the process that is writing to it, and then move it.
Have a look at the LockFileEx method in MSDN. You can use it to block until you have an exclusive lock on the file (which will happen when the writing process closes the file). Then move the file before releasing the lock.
Finally, you probably don't want to call LockFileEx from within the file system watcher callback. You may have to wait a very long time before you get the exclusive lock on the file. Instead you should queue the created files to be locked and moved by a secondary thread (or the thread pool).
string sourceFilePath = #"Your Path , ex : C:\";
string destinationFilePath = #"Your Path , ex : C:\";
System.IO.File.Move(sourceFilePath, destinationFilePath);
If you're just looking for the code to cut/paste, look into the methods: System.IO.File.Move() and System.IO.FileInfo.MoveTo(). Both do basically the same thing.

What folder does Path::GetTempFileName Method save to?

I need to get the temp file to see what happened because the actual file is never output. However, I can't seem to find where the temp file is created.
I need to find this out without writing code or building the application because there are too many dependencies scattered all over the place. I would not be able to deploy a debug version.
That method returns the path of a temporary file. The path will tell you where its pointing.
For example:
Console.WriteLine(Path.GetTempFileName());
produces:
C:\Users\will\AppData\Local\Temp\tmp9BD5.tmp
for me on this machine, because the TEMP environment variable is pointing to C:\Users\will\AppData\Local\Temp\
But the whole point of a method like GetTempFileName is that you shouldn't have to care where the file ends up. On the off-chance that you do, you can always get there at command prompts or file-open dialogs by using %TEMP%

Categories

Resources