Saving a (possibly binary) file from a URL in C#

Need a quick way to save a file (.PDF, .JPG, .ZIP, etc.) to disk from a URL?  Try this little bit of code:

public static bool SaveFileFromURL(string url, string destinationFileName, int timeoutInSeconds)
{
  // Create a web request to the URL
  HttpWebRequest MyRequest = (HttpWebRequest)WebRequest.Create(url);
  MyRequest.Timeout = timeoutInSeconds * 1000;
  try
  {
  // Get the web response
  HttpWebResponse MyResponse = (HttpWebResponse)MyRequest.GetResponse();

// Make sure the response is valid
  if (HttpStatusCode.OK == MyResponse.StatusCode)
  {
  // Open the response stream
  using (Stream MyResponseStream = MyResponse.GetResponseStream())
  {
  // Open the destination file
  using (FileStream MyFileStream = new FileStream(destinationFileName, FileMode.OpenOrCreate, FileAccess.Write))
  {
  // Create a 4K buffer to chunk the file
  byte[] MyBuffer = new byte[4096];
  int BytesRead;
  // Read the chunk of the web response into the buffer
  while (0 < (BytesRead = MyResponseStream.Read(MyBuffer, 0, MyBuffer.Length)))   {   // Write the chunk from the buffer to the file   MyFileStream.Write(MyBuffer, 0, BytesRead);   }   }   }   }   }   catch (Exception err)   {   throw new Exception("Error saving file from URL:" + err.Message, err);   }   return true; }[/sourcecode]

19 thoughts on “Saving a (possibly binary) file from a URL in C#

  1. For some reason I’m able to write 3Kb of the 1389kb file. It looks like it is getting chunked. Any ideas to solve the issue?

  2. Something else is wrong in your situation. The chunks are only written in sizes equal to MyBuffer.Length until the final segment of the file (which is file size mod MyBuffer.Length).

    I see a couple of possibilities for your scenario:

    1. The file is downloaded properly but only the first 3k are written to disk because of write errors, quota, contention, or another file issue.

    2. Your file is not being downloaded properly, or only the first 3k are being downloaded. Try opening the 3k file and see if it’s a login page, other page, etc. Try opening the URL in a browser and make sure it downloads properly that way. You can also use Fiddler to inspect the session as it happens.

    Good luck!

  3. Great work ! I was looking for this function since a long time.

    The function was failing on this call: MyRequest.GetResponse(). So I realized that I have to create a WebProxy object and assign it to the Request Object with the Proper Address and User Name/Password. This is because the web application is hosted on a Work Web Server behind a Firewall. When I used Proxy and proper credentials, it worked successfully.

    However, I am hard-coding the User Name and Password inside the Program, which is not good. In my web application, I am using Impersonation with Fixed User Name and Password. Is it possible to create the WebProxy Object and assign to it the Credential of the current impersonated User Account. Our Proxy use Windows Integrated Authentication. I want to avoid using a hard-coded user name/passord.

    Please help.

    Tarek.

  4. Tarek,

    I’d recommend storing the username and password in the web.config file. Add a project reference to System.Configuration and a web.config like so:

    <?xml version=”1.0″ encoding=”utf-8″?>
    <configuration>
    <appSettings>
    <add key=”ProxyUsername” value=”myusername” />
    <add key=”ProxyPassword” value=”mypassword” />
    </appSettings>
    </configuration>

    and then you can access them like:

    string MyUsername = ConfigurationSettings.AppSettings[“ProxyUsername”];

  5. It’s great !!
    Thank you very much for taking time to share this greeeat code !!
    very useful forme, save me hours and days of boring work !!

  6. hi
    i want save web pages with their images but your code can not save web pages images in hard disk!
    can you help me?
    thanks
    regards

  7. i have developed a method doing just like that but i got a problem …so slow in reading from the stream .it take about 20-30 sec to finish.i tried your method and i got the same time.any idea how to make it faster

Leave a comment