Carl’s Geek Notes

January 10, 2008

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

Filed under: C#/.NET, Computers, Programming — Carl @ 1:40 pm

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;
}
About these ads

19 Comments »

  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?

    Comment by Beastieboy — February 26, 2008 @ 5:55 am

  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!

    Comment by Carl — February 26, 2008 @ 8:48 am

  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.

    Comment by Tarek Faham — June 9, 2008 @ 5:54 pm

  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"];

    Comment by Carl — June 9, 2008 @ 6:08 pm

  5. thnx boss..
    i was in search of something like this for long and it worked well
    good job..
    thanx

    Comment by satheesh — July 16, 2008 @ 1:15 am

  6. I am so impressed with the code. It works as a swiss clock :)

    Thank you very much!

    Comment by Luis — August 12, 2008 @ 8:28 am

  7. 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 !!

    Comment by Victor — August 17, 2008 @ 9:07 am

  8. Great piece of code.
    Thanks for sharing

    Comment by ztek — August 26, 2008 @ 3:28 pm

  9. this is a great methode

    thanks carl!

    Comment by jp — September 10, 2008 @ 8:36 am

  10. useful information…thanks

    Comment by funpk — October 11, 2008 @ 5:32 am

  11. 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

    Comment by milad — February 21, 2009 @ 8:46 am

  12. I enjoyed reading this – very informative and useful information without a bunch of BS!

    Comment by MySpace Proxy — June 25, 2009 @ 1:06 am

  13. thanks Carl
    it worked so fast, good job

    -mandeep

    Comment by mandeep — July 20, 2009 @ 6:58 pm

  14. Thanks a lot, perfect for my coding needs.

    Comment by Josh Warner-Burke — November 2, 2009 @ 1:04 pm

  15. 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

    Comment by Ramah — July 25, 2010 @ 5:06 am

  16. Excellent post!!!

    Comment by Anyelo Roy — February 24, 2011 @ 8:07 pm

  17. Thanks ..dude…
    it really helped…

    Comment by bradley Chetty — April 12, 2011 @ 7:59 am

  18. Dude!!! You made my day!!!

    Comment by Chidi — July 27, 2011 @ 6:47 pm

  19. Works beautifully, thank you!

    Comment by Amy K — July 29, 2011 @ 9:45 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Silver is the New Black. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: