I am taking a file with a name of sfile
In my method I am doing like this way
File.Copy(sSFile, Failure + "\\" + Path.GetFileName(sSFile)) ''''''''''FAILURE FOLDER"""""
fileCounter += 1
File.move(sSFile, BACKup + "\\" + Path.GetFileName(sSFile)) ''''''''''BACKup FOLDER"""""
fileCounter += 1
where failure and backup are different folders
But it iss throwing an error : This process is using by some other process
Look at MSDN example. Hope it'll help.
Get the Path First, and then Copy the File, and then do the Same then Move the File.
I am guessing your trying to get the Filename when your already holding on to it to Copy and or Move It.
Use
File.Copy(sSFile, Path.Combine(Failure, Path.GetFileName(sSFile)), bool_overrideflag);
Related
I am trying to save a backup of some data. If the backup exists then I want to delete it, give the most recent file the name of the backup file, and then save the new file as the most recent file.
The problem I am running into is that when I delete an existing file I still cannot save another file under the same name. The system still thinks that the file exists, and indeed the file isn't deleted at the point where the program throws the exception even though the two lines are right after each other. The only thing I can think of is that that the "delete" operation hasn't had time to complete by the time the move operation wants to execute. But I do not know how to fix it.
The code looks something like this.
File.Delete(filePath.Substring(filePath.Length - 4) + ".bak");
File.Move(filePath, filePath.Substring(0, filePath.Length - 4) + ".bak");
I thought of setting a timer in order to execute the move function later, but it seems to me that this would probably be a very sloppy and dangerous way of handling the problem. In addition, the amount of time that one needs to wait might have to vary from system to system. So I am thinking that there must be a better way.
The problem has probably to do with the fact that you use two different .Substring methods: String#Substring(int) and String#Substring(int,int). Indeed:
File.Delete(filePath.Substring(filePath.Length - 4) + ".bak");
// ^ with one int
File.Move(filePath, filePath.Substring(0, filePath.Length - 4) + ".bak");
// ^ with two ints
And unfortunately, the two are not semantically equivalent. The one with one int is the start index. So given that filePath is equal to test.txt, the file you aim to remove is .txt.bak and next you aim to move a file to test.bak. Or running this with Mono's C# emulator:
csharp> String filePath = "test.txt";
csharp> filePath.Substring(filePath.Length - 4) + ".bak"
".txt.bak"
csharp> filePath.Substring(0, filePath.Length - 4) + ".bak"
"test.bak"
Please update it with:
File.Delete(filePath.Substring(0,filePath.Length - 4) + ".bak");
// ^ added zero
File.Move(filePath, filePath.Substring(0, filePath.Length - 4) + ".bak");
Another more elegant and less error prone way is evidently to use a variable in between such that you are sure, you are talking about the same file:
String backupfile = filePath.Substring(0, filePath.Length - 4) + ".bak";
File.Delete(backupfile);
File.Move(filePath,backupfile);
Finally it's not recommended to do path processing yourself: use dedicated methods to join and manipulate file paths.
I tried your code with a little change and it worked fine. I only changed how you defined the backup file name, because the file extension can be more or less than 3 chars:
string backupPath = Path.GetFileNameWithoutExtension(filePath) + ".bak";
File.Delete(backupPath);
File.Move(filePath, backupPath);
But if it does not work for you, try to rename the backup to lets say "*.bak2" and then delete that one.
Hope that helps...
I am trying to create a directory from a textbox and also save name from the same textbox input as file name. Tried it several ways but its just keeps shooting out errors unknow. No matter what way i write it maybe i am missing something. I like to know where i am going wrong.
This is the only way that doesnt show an error till i run it then says unknown. Any help would be great.
private void savePictureBox_Click(object sender, EventArgs e)
StreamWriter File = new StreamWriter(#"C:\" + modNameTextBox .ToString() + modNameTextBox + ". txt");
File.Writer(aboutRichTextBox);
File.Close();
Here's a solution that should get you started.
string filePath = #"C:\" + modNameTextBox .ToString() + modNameTextBox + ". txt";
string folder = Path.GetDirectoryName(filePath);
if(!Directory.Exists(folder))
{
Directory.Create(folder);
}
File.WriteAllText(filepath, aboutRichTextBox);
Note that you will need to add some Using statements for Path, File, and Directory.
A proper solution will handle the case of a user not typing in a valid directory in the textbox, but that can get a bit complicated (I recommend using SaveFileDialog instead.)
I'm making an Outlook plugin which will automatically save messages to a file server when received. This part of the code simply doesn't do what it's asked to do!
//RelevantDirectory[0] is the root folder where I want to save stuff, and sits on a mapped network drive where I have full admin permissions.
System.IO.Directory.CreateDirectory(RelevantDirectory[0] + "\\Email Correspondence\\");
System.IO.Directory.CreateDirectory(RelevantDirectory[0] + "\\Email Correspondence\\Outgoing");
mail.SaveAs(RelevantDirectory[0] + "\\Email Correspondence\\Outgoing\\" + mail.SenderName + " - " + string.Format("text-{0:yyyy-MM-dd_hh-mm-ss-tt}", mail.ReceivedTime) + ".msg");
System.Windows.Forms.MessageBox.Show(System.IO.File.Exists(RelevantDirectory[0] + "\\Email Correspondence\\Outgoing\\" + mail.SenderName + " - " + string.Format("text-{0:yyyy-MM-dd_hh-mm-ss-tt}", mail.ReceivedTime) + ".msg").ToString()); //returns True!
The MessageBox returns True, yet the file isn't actually there! The CreateDirectory code also doesn't create the directory - and I'm sure that the filepath in the program is correct. I understand from this link that this could have something to do with filesystem virtualisation. If so, how do I get around the problem?
One more point is that if I point mail.SaveAs to the Desktop folder, it saves it.
EDIT For some bizarre reason, using Path.Combine() worked. Credit to Sinatr. Thanks for your hints everyone.
The problem is in the line:
string.Format("text-{0:yyyy-MM-dd_hh-mm-ss-tt}", mail.ReceivedTime)
When converted to string it becomes somthing like : 1/1/2014 12:35:35 PM
when creating files a '/' and ':' are illegal characters , so for the minimal amount change I suggest you append a couple Replace functions at the end of your string.Format like this:
string.Format("text-{0:yyyy-MM-dd_hh-mm-ss-tt}", mail.ReceivedTime).Replace('/','-').Replace(':',' ')
I know a few similar questions have been asked on how to download files using WebClient. I can download individual files perfectly fine, but I want to download a range of files. Anywhere from 1-6000 files. I can download them just fine into my current directory, but I am stumped on how to download them to a different directory based upon where they're being downloaded from. Do I need to temporarily change the current working directory just before downloading them?
And slightly on the same topic, I'm stuck on how to verify the files exist before downloading them. I don't want to waste bandwidth or diskspace with empty files.. Here's what I have so far:
for (int x = 1; x <= 6000; x++)
{
pbsscount = x.ToString();
// Used for downloading file
string directoryName = textBox1.Text.ToString().Replace(":", "_");
if (!Directory.Exists(textBox1.Text))
Directory.CreateDirectory(directoryName.Substring(7));
string wholePBSSurl = textBox1.Text + "/" + "pb" + pbsscount.PadLeft(6, '0') + ".png";
// Used for saving file, file name in directory
string partPBSSurl = "pb" + pbsscount.PadLeft(6, '0') + ".png";
Uri uri2 = new Uri(wholePBSSurl);
//if (fileExists(wholePBSSurl))
//{
// Initialize downloading info, grab progressbar info
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
// Save file to folder
//webClient.DownloadFileAsync(uri2, textBox1.Text + "/" + partPBSSurl);
webClient.DownloadFileAsync(uri2, partPBSSurl);
//}
}
Do I need to temporarily change the current working directory just before downloading them?
The second parameter can be a full path #"C:\folder\file.png". If you're fine with relative path to your current directory, just change the code to webClient.DownloadFileAsync(uri2, directoryName + partPBSSurl); or even better use System.Path.Combine(directoryName, partPBSSurl)
Sure you can know the size before If sever supports that. See: How to get the file size from http headers
I don't want to waste bandwidth or diskspace with empty files.
I wouldn't worry about that. The performance slow down is negligible.
There is no need to change the current directory. You are already using an overload of DownloadFileAsync that accepts a file path as the second parameter.
Just ensure that partPBSSurl contains a full path to the destination file, including both the directory and filename.
With regard to your second question of avoiding wasted time if the file does not exist, it so happens that I asked the same question recently:
Fail Fast with WebClient
Finally, I recently extended WebClient to provide simpler progress change events and allow for the timeout to be changed. I posed that code here:
https://stackoverflow.com/a/9763976/141172
We are using an application that reads the file and inserts into database. For some reason, we set the creation time to a particular time. and when we create the file the application picks up the file before we even change the creation time. Is there anyway that we can lock the file until we change its creation time.
The error i am getting is at File.SetCreationTime as the file is being used by other process or the file is archived.
//Copy signal file
s = filePath + "s";
newS = targetFullPath2 + "s";
File.Copy(s, newS, true);
//
//new creation ts
dtFileCreation = File.GetCreationTime(s);
//retain creation time
File.SetCreationTime(newS, dtFileCreation);
Please advice.
The common solution to this is to create the file (and set its timestamp) in a different directory or under a different name first, and then move or rename it when it’s ready so the other process can pick it up. The move/rename is an atomic operation on NTFS (unless of course you move files between separate partitions).
For example:
s = filePath + "s";
newS = targetFullPath2 + "s";
File.Copy(s, newS + "_", true); // add the _ so the other process
// doesn’t “see” the file yet
dtFileCreation = File.GetCreationTime(s);
File.SetCreationTime(newS + "_", dtFileCreation);
// We’re done with the file, now rename it to its intended final name
File.Move(newS + "_", newS);
That error indicates someone (it could be you or another program) is locking the file; therefore, I do not think locking the file will solve your problem. What kind of file is it? Is your code reading the file and forgetting to close the stream after it is done?