Как скачать файл по http?

Для того что бы скачать файл по протоколу http на C# потребуется написать всего несколько строчек и подключить пространство имен System.Net.

Самый простой, но не самый наглядный способ.

Просто как две строчки написать:

WebClient webClient = new WebClient();
webClient.DownloadFile("http://mysite.com/myfile.txt", @"c:\myfile.txt");


Но никакого отображения процесса загрузки файла не происходит, что конечно же не устраивает нетерпеливых пользователей.

Скачка файла с отображением процесса загрузки.

Для загрузки файла по http не блокируя при этом основного потока необходимо воспользоваться методом DownloadFileAsync. Также можно обработать событие DownloadProgressChanged для индикации процесса загрузки файла и событие DownloadFileCompleted для определения момента, когда файл будет полностью загружен.

private void btnDownload_Click(object sender, EventArgs e)
{
  WebClient webClient = new WebClient();
  webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
  webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
  webClient.DownloadFileAsync(new Uri("http://mysite.com/myfile.txt"), @"c:\myfile.txt");
}

private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
  progressBar.Value = e.ProgressPercentage;
}

private void Completed(object sender, AsyncCompletedEventArgs e)
{
  MessageBox.Show("Download completed!");
}

Скачка файла с отображением процесса загрузки при помощи WebRequest.

Для того что бы скачать файл с помощью класса WebRequest потребуется немного больше усилий чем в способах описанных выше и особой выгоды от этого не будет, но рассмотреть их тоже стоит.

Для этого необходимо послать запрос по необходимому адресу и в ответе будет содержаться ссылка на поток с данными:

HttpWebRequest _req = (HttpWebRequest) WebRequest.Create(“http://mysite.com/myfile.txt”);
WebResponse _response = _req.GetResponse();
Stream _stream = _response.GetResponseStream();

Для того что бы сохранить данные на диске необходимо в цикле прочитать содержимое потока полученного в результате выполнения запроса, например вот так:

FileStream _fs = new FileStream(“myfile.txt”, FileMode.Create)

int _bytesRead = 1;
while (_bytesRead != 0)
{
byte[] buffer = new byte[1024];
_bytesRead = _stream.Read(buffer, 0, buffer.Length);
      _fs.Write(buffer, 0, buffer.Length);
}

Запустив все эти действия в отдельном потоке, в основном потоке можно отображать процесс загрузки. Так как работать с визуальными компонентам инеобходимо из потока в котором они создавались, то для изменения например ProgressBar стоит воспользоваться методом Invoke():

public delegate void dClose();
private delegate void dProgressInit(ProgressBar aPb, Int32 aMaxValue);
private delegate void dProgressValue(ProgressBar aPb, Int32 aValue);

private void ProgressInit(ProgressBar aPb, Int32 aMaxValue)
{
aPb.Maximum = aMaxValue;
}

private void ProgressValue(ProgressBar aPb, Int32 aValue)
{
aPb.Value = aValue;
}

private void DownloadFiles()
{

HttpWebRequest _req = (HttpWebRequest)WebRequest.Create(item.Link);
WebResponse _response = _req.GetResponse();

Invoke(new dProgressInit(ProgressInit), new object[] { pbBytes,(Int32)_response.ContentLength });
      Invoke(new dProgressValue(ProgressValue), new object[] { pbBytes, 0 });

using (Stream _stream = _response.GetResponseStream())
{
          using (FileStream _fs = new FileStream(@"c:\test.txt",FileMode.Create))
            {
                  int _bytesRead = 1;
                  while (_bytesRead != 0)
                  {
                      byte[] buffer = new byte[32768];

                        _bytesRead = _stream.Read(buffer, 0, buffer.Length);
                        _fs.Write(buffer, 0, buffer.Length);

buffer = null;

Invoke(new dProgressValue(ProgressValue), new object[] { pbBytes, pbBytes.Value + _bytesRead });
                        Invoke(new dClose(pbBytes.Refresh));
                  }
           }
      }
}

Особое внимание в этом способе загрузки следует уделить размеру буфера (byte[] buffer = new byte[32768];) т.к. это влияет на скорость и качество загрузки. Чем меньше буфер, тем необходимо потратить больше ресурсов (времени) на запрос следующей части, но меньше вероятность сбоя подключения и соответственно наоборот.

Currently rated 4.8 by 6 people

  • Currently 4.833333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

Comments

Add comment


 

biuquote
  • Comment
  • Preview
Loading