加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – HttpClient在上传前读取整个文件. UWP

发布时间:2020-12-15 06:33:45 所属栏目:百科 来源:网络整理
导读:我正在制作一个将文件上传到Facebook的UWP应用程序,我正在使用自定义的HttpContent来将文件上传到4k块,以最大限度地减少大文件( 100mb)的内存使用情况并报告进度. 我的自定义HttpContent UploadWithProgressHttpContent: class UploadWithProgressHttpConte
我正在制作一个将文件上传到Facebook的UWP应用程序,我正在使用自定义的HttpContent来将文件上传到4k块,以最大限度地减少大文件(> 100mb)的内存使用情况并报告进度.

我的自定义HttpContent UploadWithProgressHttpContent:

class UploadWithProgressHttpContent : HttpContent
{
    private readonly IProgress<OperationProgress> _progress;
    private readonly OperationProgress _data;
    private readonly Stream _file;
    private readonly int _bufferSize;
    private readonly CancellationToken _token;

    public UploadWithProgressHttpContent(
        IProgress<OperationProgress> progress,OperationProgress data,Stream file,int bufferSize,CancellationToken token)
{
    _progress = progress;
    _data = data;
    _file = file;
    _bufferSize = bufferSize;
    _token = token;
}



protected override Task SerializeToStreamAsync(Stream stream,TransportContext context)
{
    return CopyStreamWithProgress(_file,stream,_progress,_token,_data,_bufferSize);
}

public static async Task<Stream> CopyStreamWithProgress(
    Stream source,Stream destination,IProgress<OperationProgress> progress,CancellationToken token,OperationProgress progressData,int bufferSize
    )
{
    int read,offset = 0;
    var buffer = new byte[bufferSize];
    using (source)
    {
        do
        {
            read = await source.ReadAsync(buffer,bufferSize,token);

            await destination.WriteAsync(buffer,read,token);

            offset += read;
            progressData.CurrentSize = offset;
            progress.Report(progressData);
        } while (read != 0);
    }

    return destination;
}
}

我使用(使用fiddler)的是,在上传开始之前,整个文件被放入内存(我的进度计在上传甚至启动之前达到了100%).

我确实尝试将TransferEncodingChunked设置为true,并设置文件内容长度,但仍然存在问题.

上传源在PCL内(如果重要).我正在使用最新版本的System.Net.Http.如果需要我正在使用它与MediaFire SDK中使用的完全相同的方式

感谢任何帮助.

编辑:添加了HttpClient用法:

public async Task<T> Upload<T>(Stream fileStream,string fileName)
{
    var handler = new HttpClientHandler();


    var cli = new HttpClient(handler);

    foreach (var header in Headers)
    {
        cli.DefaultRequestHeaders.Add(header.Key,header.Value);
    }

    var parameters = new MultipartFormDataContent();
    foreach (var parameter in Parameters)
    {
        parameters.Add(new StringContent(parameter.Value),parameter.Key);
    }

    if (fileStream != null)
    {
        var fileContent = new UploadWithProgressHttpContent(ProgressOperation,ProgressData,fileStream,_chunkBufferSize,Token,fileStream.Length);

        fileContent.Headers.ContentType = new MediaTypeHeaderValue(MimeTypeHelper.GetMimeType(fileName));
        fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue(StreamParamName);
        fileContent.Headers.ContentDisposition.FileName = fileName;
        fileContent.Headers.ContentLength = fileStream.Length;
        parameters.Add(fileContent,StreamParamName);
    }

    var req = new HttpRequestMessage(method,Path) { Content = parameters };
    if (fileStream != null)
        req.Headers.TransferEncodingChunked = true;


    var completionOption = HttpCompletionOption.ResponseContentRead;


    var resp = await cli.SendAsync(req,completionOption,Token).ConfigureAwait(false);

    return await DeserializeObject<T>(resp);
}

解决方法

你有与量子力学相同的问题 – 观察观察变化的行为. Fiddler不支持请求流 – 请参阅
Fiddler makes HttpWebRequest/HttpClient behaviour unexpected

http://www.telerik.com/forums/is-it-possible-to-not-buffer-requests

使用wireshark我可以看到大块.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读