Загрузка торрент-файла с WebClient приводит к повреждению файла - PullRequest
3 голосов
/ 25 марта 2012

Я пытаюсь загрузить файл .torrent (не содержимое самого торрента) в мое приложение .NET.

Использование следующего кода работает для других файлов, но не для .torrent. Получающиеся файлы примерно на 1-3 КБ меньше, чем если бы я загружал файл через браузер. Когда он открывается в торрент-клиенте, он говорит, что торрент поврежден.

WebClient web = new WebClient();
web.Headers.Add("Content-Type", "application/x-bittorrent");
web.DownloadFile("http://kat.ph/torrents/linux-mint-12-gnome-mate-dvd-64-bit-t6008958/", "test.torrent");

Открытие URL в браузере приводит к правильной загрузке файла.

Есть идеи, почему это произойдет? Есть ли хорошие альтернативы WebClient, которые бы правильно загружали файл?

РЕДАКТИРОВАТЬ: я пробовал это так же, как WebClient, и это приводит к тому же:

private void DownloadFile(string url, string file)
    {
        byte[] result;
        byte[] buffer = new byte[4096];

        WebRequest wr = WebRequest.Create(url);
        wr.ContentType = "application/x-bittorrent";
        using (WebResponse response = wr.GetResponse())
        {
            using (Stream responseStream = response.GetResponseStream())
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    int count = 0;
                    do
                    {
                        count = responseStream.Read(buffer, 0, buffer.Length);
                        memoryStream.Write(buffer, 0, count);

                    } while (count != 0);

                    result = memoryStream.ToArray();

                    using (BinaryWriter writer = new BinaryWriter(new FileStream(file, FileMode.Create)))
                    {
                        writer.Write(result);
                    }
                }
            }
        }
    }

1 Ответ

5 голосов
/ 25 марта 2012

Проблема в том, что сервер возвращает содержимое, сжатое gzip , и вы загружаете это сжатое содержимое в файл.В таких случаях вы должны проверить заголовок «Content-Encoding» и использовать соответствующий потоковый ридер для распаковки источника.Я изменил вашу функцию для обработки сжатого содержимого:

private void DownloadFile(string url, string file)
    {
        byte[] result;
        byte[] buffer = new byte[4096];

        WebRequest wr = WebRequest.Create(url);
        wr.ContentType = "application/x-bittorrent";
        using (WebResponse response = wr.GetResponse())
        {
            bool gzip = response.Headers["Content-Encoding"] == "gzip";
            var responseStream = gzip
                                    ? new GZipStream(response.GetResponseStream(), CompressionMode.Decompress)
                                    : response.GetResponseStream();

            using (MemoryStream memoryStream = new MemoryStream())
            {
                int count = 0;
                do
                {
                    count = responseStream.Read(buffer, 0, buffer.Length);
                    memoryStream.Write(buffer, 0, count);
                } while (count != 0);

                result = memoryStream.ToArray();

                using (BinaryWriter writer = new BinaryWriter(new FileStream(file, FileMode.Create)))
                {
                    writer.Write(result);
                }
            }
        }
    }
...