Reputation: 40345
I'm trying to download a file from the web and save it locally, but I get an exception:
C# The process cannot access the file 'blah' because it is being used by another process.
This is my code:
File.Create("data.csv"); // create the file
request = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
request.Timeout = 30000;
response = (HttpWebResponse)request.GetResponse();
using (Stream file = File.OpenWrite("data.csv"), // <-- Exception here
input = response.GetResponseStream())
{
// Save the file using Jon Skeet's CopyStream method
CopyStream(input, file);
}
I've seen numerous other questions with the same exception, but none of them seem to apply here. Any help?
Update:
Thanks for the answers! Removing the File.Create(...)
fixed it!
One comment on the documentation of OpenWrite
: it is a little misleading, the brief description says:
Opens an existing file for writing.
The detailed description says:
If the file exists, it is opened for writing at the beginning. The existing file is not truncated.
Update 2.0:
It looks like the discrepancy is between IntelliSense/F1 and the online documentation. I thought it should be the same since I allow F1 to connect to the web when it's displaying documentation.
Upvotes: 7
Views: 6705
Reputation: 12485
The problem is that the File.Create method actually opens the file and returns a FileStream object. It won't close the file until the object is garbage collected (which will happen at an indeterminate time). The FileStream object still gets created, regardless of whether or not you use it. Try this:
using (Stream file = File.Create("data.csv"),
input = response.GetResponseStream())
{
// Save the file using Jon Skeet's CopyStream method
CopyStream(input, file);
}
Upvotes: 4
Reputation: 20614
looks like File.Create returns an open FileStream object
http://msdn.microsoft.com/en-us/library/aa328775(v=VS.71).aspx
try
using (FileStream fs = File.Create("data.csv"))
and leave off the first File.Create
Upvotes: 6
Reputation: 38367
First. File.Create will return a stream that you should use for accessing the file.
Second, if that doesn't resolve the issue, if you google who lock
you will find a program that let's you determine what process is accessing a file at the same time.
Upvotes: 3
Reputation: 1500514
File.Create
returns a FileStream
- which you're not closing. That means you won't be able to open another stream writing to the same file until the finalizer has closed the existing stream.
Just get rid of the call to File.Create
- File.OpenWrite
will create it anyway. Alternatively, keep the FileStream
around to write to:
using (Stream file = File.Create("data.csv"))
{
request = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
request.Timeout = 30000;
using (var response = (HttpWebResponse)request.GetResponse())
using (Stream input = response.GetResponseStream())
{
// Save the file using Jon Skeet's CopyStream method
CopyStream(input, file);
}
}
Note that I'm also disposing of the WebResponse
here, which you should do to make sure the connection is freed to the connection pool.
Upvotes: 18