How to read a binary file over HTTP and write to disk using ASP.NET and C#

By Michael Argentini
Managing Partner, Technology and Design

Have you ever had the need to grab a binary file from a remote server over HTTP, and save it to your server, using ASP.NET? It may not sound like a common request, or even a difficult one. But there are a few tricks to accomplishing your goal. One challenge I encountered was that using a BinaryReader required some buffering code. A blind call to read the stream would often only return a portion of the file.

The following C# method works quite well, no matter how fast or reliable your internet connection is. Can you feel the love I put into this gem? Oh, wait. That's just gas.

The Method...

/// Read a binary file from a URL and write it to disk.
/// URL: URL to the web resource.
/// FilePath: Web-style path for the destination file on disk, including
/// new file name.
/// RETURNS: Number of bytes read, or zero if no file was returned.

public static Int64 WriteBinaryFile(String URL, String FilePath)
{
    Int64 bytesWritten = 0;

    try
    {
        WebResponse objResponse;
         objResponse = WebRequest.Create(URL).GetResponse();
         Byte[] ByteBucket = new Byte[objResponse.ContentLength];
         BinaryReader readStream = new BinaryReader(
                 objResponse.GetResponseStream());
         FileStream fileToWrite =
                  new FileStream(HttpContext.Current.Server.MapPath(
                  FilePath), FileMode.Create, FileAccess.Write);

         Int32 currentBytesRead = 0;
         Int32 totalBytesRead = 0;
         Boolean done = false;

         #region Use a buffer to prevent truncated files

         while (!done)
         {
                  currentBytesRead = readStream.Read(ByteBucket, 0,
                          Convert.ToInt32(objResponse.ContentLength));
                  fileToWrite.Write(ByteBucket, 0, currentBytesRead);

                  totalBytesRead += currentBytesRead;

                  if (totalBytesRead == objResponse.ContentLength)
                  {
                           done = true;
                  }
         }

         #endregion

         fileToWrite.Close();

         bytesWritten = objResponse.ContentLength;
    }

    catch
    {
         bytesWritten = 0;
    }

    return bytesWritten;
}

Calling the Method...

public void test()
{
    Int64 bytesRead =
        WriteBinaryFile("http://yourdomain.com/file.pdf",
             "/files/downloaded.pdf");
}

Article last updated on 4/21/2018