문제

HTTP를 통해 파일을 다운로드하는 프로그램을 만들고 있습니다.

다운로드를 받았지만 다운로드를 일시 중지하고 프로그램을 닫고 나중에 다시 재개 할 수 있습니다.

나는 내가 이것을 지원하는 위치를 알고 있습니다.

httpwebresponse를 통해 파일을 다운로드하고 getResponseStream을 사용하여 응답을 스트림으로 읽고 있습니다.

앱을 닫고 다시 시작하면 다운로드를 재개하는 방법에 대해 고정되었습니다. 나는 스트림을 찾아 보려고 노력했지만 지원되지 않는 것으로 나타났다.

이것을하는 가장 좋은 방법은 무엇입니까?

도움이 되었습니까?

해결책

서버가 이것을 지원하는 경우 범위 HTTP 헤더를 사용한 요청이 있습니다 addrange 방법:

request.AddRange(1024);

이렇게하면 서버가 첫 번째 킬로바이트 후 파일을 보내도록 지시합니다. 그런 다음 응답 스트림을 정상적으로 읽으십시오.

서버가 재개를 지원하는지 테스트하려면 HEAD 보내는 경우 요청하고 테스트하십시오 Accept-Ranges: bytes 헤더.

다른 팁

Httprangestream 클래스는 어떻습니까?

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;

namespace Ionic.Kewl
{
    public class HTTPRangeStream : Stream
    {
        private string url;
        private long length;
        private long position;
        private long totalBytesRead;
        private int totalReads;

        public HTTPRangeStream(string URL)
        {
            url = URL;
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            HttpWebResponse result = (HttpWebResponse)request.GetResponse();
            length = result.ContentLength;
        }

        public long TotalBytesRead    { get { return totalBytesRead; } }
        public long TotalReads        { get { return totalReads; } }
        public override bool CanRead  { get { return true; } }
        public override bool CanSeek  { get { return true; } }
        public override bool CanWrite { get { return false; } }
        public override long Length   { get { return length; } }

        public override bool CanTimeout
        {
            get
            {
                return base.CanTimeout;
            }
        }


        public override long Position
        {
            get
            {
                return position;
            }
            set
            {
                if (value < 0) throw new ArgumentException();
                position = value;
            }
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            switch (origin)
            {
                case SeekOrigin.Begin:
                    position = offset;
                    break;
                case SeekOrigin.Current:
                    position += offset;
                    break;
                case SeekOrigin.End:
                    position = Length + offset;
                    break;
                default:
                    break;
            }
            return Position;
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.AddRange(Convert.ToInt32(position), Convert.ToInt32(position) + count);
            HttpWebResponse result = (HttpWebResponse)request.GetResponse();
            using (Stream stream = result.GetResponseStream())
            {
                stream.Read(buffer, offset, count);
                stream.Close();
            }
            totalBytesRead += count;
            totalReads++;
            Position += count;
            return count;
        }


        public override void Write(byte[] buffer, int offset, int count)
        {
            throw new NotSupportedException();
        }

        public override void SetLength(long value)
        {
            throw new NotSupportedException();
        }
        public override void Flush()
        {
            throw new NotSupportedException();
        }

    }
}

솔루션은 괜찮지 만 서버가 컨텐츠 길이 헤더를 보내는 경우에만 작동합니다. 이 헤더는 동적으로 생성 된 컨텐츠에 존재하지 않습니다.

또한이 솔루션은 각 읽기에 대한 요청을 보냅니다. 요청간에 서버의 컨텐츠가 변경되면 일관되지 않은 결과가 나타납니다.

디스크 또는 메모리에 데이터를 로컬로 저장하여이를 향상시킬 것입니다. 그런 다음 원하는 모든 것을 찾을 수 있습니다. 불일치 문제는 없으며 다운로드하려면 하나의 httpwebrequest 만 있으면됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top