I can't find any information on my question. Please excuse me if my search efforts have not been good enough to find the answer. I just want to avoid spinning my wheels.
Thanks!
Follow up: If it doesn't overwrite, how can I get it to (if possible)?
A 30 second test confirms that it does overwrite
Test:
using (WebClient client = new WebClient())
{
client.DownloadFileAsync(new Uri("http://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe"), #"C:\Test.exe");
}
Test.exe is overwitten if downlaoded again
The WebClient class is obviously designed to suppress a lot of detail and control. You can write your own method to asynchronously download a file very easily and control how the downloaded data is written to disc.
I know for sure that this solution at codeproject contains a class which downloads a file using WebRequest and WebResponse which allows for much more control. See the class contained named webdata. The code you can need to pay attention too:
FileStream newFile = new FileStream(targetFolder + file, FileMode.Create);
newFile.Write(downloadedData, 0, downloadedData.Length);
newFile.Close();
The FileMode Enumeration contains a series of members that dictate the behaviour of saving a file FileMode.CreateNew will throw an IOException if a file already exists. As where FileMode.Create will overwrite files if possible.
If you insist on using WebClient.DownloadFileAsync then, as the other fellas have already mentioned: you can just inform the user that an existing file will be overwritten by means of an OpenFileDialog but some downloads can be time consuming and there's nothing to say that the user has not created another file during the download.
If the file exists, yes.
If you are renaming it, or if you have it hooked into an OpenFileDialogue(), that's your discretion.
Related
I have this link: http://www.bnro.ro/nbrfxrates.xml to an xml file with daily Currency.
I want to save this xml in folder of my website ex. (~/Content/CurrencyXml).
I want to save it every day, first time when a user is accessing my website (must replace the old file).
I want also to read it in a static method which return an object with each currency type like property, in order to access it something like this:
price=model.Eur * 100;
Can you help me with an example of how to save a copy of this xml and how to read it?
You can try something like this to read the file and save it
public void readFile()
{
XmlDocument document = new XmlDocument();
document.Load("http://www.bnro.ro/nbrfxrates.xml");
document.Save(Path.Combine(
Server.MapPath("~/Content/CurrencyXml"),"myFile.xml"));
}
and in here you can find very usefull information:
XmlDocument Microsoft
Here's an example for the windows service:
Walkthrough: Creating a Windows Service Application in the Component Designer
Here's an example on how to download xml using WebClient:
How can I download an XML file using C#?
Here's an example on how to save a file to your server:
C# save files to folder on server instead of local
Then use what #Augustin suggested.
If you do use the flag file scenario, I would advice to save the xml file to a temporary file and only when fully downloaded, overwrite your original one and make sure to handle locking, overwriting time, etc... One other solution would be to use a temp variable that holds the current filename and when you download a new file, just give it a new name and when downloaded, set that variable name to the new filename and make sure that your load function uses that variable and loads the data from the new filename. Don't forget to delete your old file(s), but at least it will avoid locking issues if any and you can always try to delete the file later again.
If will very much depend if your website if being access 24/7 or not. If it isn't it is less of an issue as you could use the windows service to download this file when you know it's not being used. If you use the windows service, while being used, same as above would apply. If you're using Azure, you could use a WebJob. I'm sure there are many different solutions to handle this and you just have to find the one that will meet your needs.
I have some code that saves a string to a file, something like this:
string TheFileJS = HttpRuntime.AppDomainAppPath + "\\SomePath\\" + ClientFileName + ".js";
if (File.Exists(TheFileJS) == true)
{
File.Delete(TheFileJS);
}
File.WriteAllText(TheFileJS, TheJS);
I'm using File.WriteAllText because I thought it would prevent problems with file locking but what's happening is that sometimes I get the error File is being used by another process. The problem is that it rarely happens, but once this exception occurs on a particular file, all client calls to this file then result in a 404.
What do I need to change in my code to make sure this error never happens?
I would imagine that you are running into problems with the lock still being open after the delete causing you to be unable to then rewrite the file.
The good news is that this is easily solvable by not deleting the file first.
From the docs for WriteAllText it says "Creates a new file, writes the specified string to the file, and then closes the file. If the target file already exists, it is overwritten."
What this means is that it effectively deletes the contents of the file anyway so checking if the file exists first is unnecessary. If you are not doing that check then you shouldn't run into any problems.
This is also where exception handling would come in handy. If this is critical code then you could retry or alert an admin immediately of the problem hopefully preventing all your clients then 404ing.
Try this. During file creation, if any stream is opened, it will be closed.
FileStream stream = File.Create(TheFileJS);
stream.Close();
I am trying to create a new file and write XML to it:
FileStream output = File.Create(Path.Combine(PATH_TO_DATA_DIR, fileName));
The argument evaluates to:
C:\path\to\Data\test.xml
The exception is:
The process cannot access the file 'C:\path\to\Data\test.xml' because it is being used by another process.
What am I doing wrong here?
UPDATE: This code throws the same exception:
StreamWriter writer = new StreamWriter(Path.Combine(PATH_TO_DATA_DIR, fileName));
UPDATE 2: The file I am trying to create does not exist in the file system. So how can be it in use?
UPDATE 3: Changed to a new file name, and now it works. I'm not sure why. Perhaps I unknowing created it in the first call, and it failed on subsequent calls?
The message means that another process is using that file. If you have it open it could be using it, or when it was originally created if the stream was not closed properly that could do it also.
First check to make sure you do not have it open. I would try to change the fileName and see if you get the same error. If you do get the same error than some place in your code it is not closing a stream that when it is done with the file.
Your program keeps a handle on your file after it's being created to return to your FileStream object. Because you don't specify the access to it, perhaps it won't let you get a grab on it. Perhaps should you consider closing it, and then reopen it in a proper manner by specifying how you want it open (ReadOnly, ReadWrite, WriteOnly) ?
Not trying to sound insulting, but does the folder exist? Does the file already exist but is hidden by the system? And does the user account that is running the program have write permissions to the folder? Have you tried creating a file using a different method (like with File.WriteAllText(<path>, "Testing") just to see if it's your particular call to File.Create?
I have many processes reading a file stored on a network share. Originally I was only able to have one process read the file, all the others would throw exceptions. I implemented the following code to deal with that:
using (StreamReader fileStreamReader = new StreamReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)))
{
content = fileStreamReader.ReadToEnd();
}
This let multiple processes read the same file, however it still seems to have issues, because sometimes multiple processes still can't access the file. Yet I can go back later when the file isn't in use and open it just fine. Right now I have some retry behavior with random delays implemented that so far, seem to help. It seems a little quirky to me to do it this way, so what would be a better method?
This is the weird part, the exception I'm getting is not from file IO at all, it's from a library called CommStudio. In short, I dump the file to a string, i modify it slightly, dump it into a memory stream, and ship it off over ymodem on rs232. The exception is telling me the remote system has canceled. The device getting the data reports that there was a transmission error, which usually means that an incomplete/empty file was received.
Normally I would blame the library on this, but it works flawlessly at desk-testing and when there is only one process accessing the file. The only thing that really seems to be consistent is that it is likely to fail when multiple processes are accessing a file.
had a similar problem but not allot of time to find an ideal solution. I created a webservice and stuck the file local to the webservice app.. then created a simple one liner GET API which was called over the office intranet.. thus ensureing only the calling application edited the log file.. messy but functional.
I have had a similar problem in the past. Try changing how you access the file to something like this.
//Use FileInfo to get around OS locking of the file
FileInfo fileInfo = new FileInfo(path);
//I actually wanted unblocked read write access so change your access and share appropriately
using (FileStream fs = fileInfo.Open(FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
{
//I'm using CopyTo but use whatever method matches your need
fileInfo.CopyTo(Path.Combine(destination, fileName), false);
}
I'm writing a Windows Service that needs to take a file from an FTP folder on the local computer and parse the data in that file, and push it to an external source. The file will be uploaded to the FTP folder at some point from some other party, and I can't predict when the file will be uploaded. I need the service to be able to scan the FTP folder and recognize when the file has been recently uploaded to the server, and kick off the parsing process.
I need some know if there's some way in .NET to be able to detect when a file was put into a directory.
There is a similar question in SO about this here, but it wasn't in regards to writing a windows service. Also, the solution seemed to be to monitor the directory itself, but I tested that idea using the DirectoryInfo class and it doesn't work when looking at the LastWriteTime property. The time of the directory doesn't change when I copy and replace a file in the directory.
Note: I can't rely on the create/modify timestamps on the file, being as I don't know how the other party is generating these files.
Use a FileSystemWatcher. That will throw a "Changed" (Or even a "created" I believe) event which you can handle. You'll need to be careful to make sure the file is fully written before you start working with it, but that should get you pointed in the right direction.
EDIT: To Joseph's question about how, here's a static method I keep in my utilities class for just such occasions:
public static bool FileComplete(string filePath)
{
try
{
File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
return true;
}
catch { return false; }
}
Then I just a While(!FileComplete(foo)) {} before my actual file handling.
Take a look at FileSystemWatcher.