通过使用http请求检索的流保存大文件 [英] Saving large file by a stream retrieved using an http request

查看:98
本文介绍了通过使用http请求检索的流保存大文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在保存http请求收到的文件时遇到问题。如果我在byte []中复制流应用程序内存不足,所以我尝试使用inputstream / outputstream ...但输入流的canseek属性是 等于假
所以我不能使用inputstream.position和inputstream.lenght ...我该如何解决这个问题?

Hi, i have a problem with saving a file received by an http request. If i copy the stream in a byte[] the application run out of memory, so i tried to do with inputstream/outputstream...but the canseek property of the inputstream is  equal to false and so i cannot use inputstream.position and inputstream.lenght...how can i solve this?

这里代码:

 //i receive a stream by an http request
var stream = await response.Content.ReadAsInputStreamAsync();
Stream inputStream = stream.AsStreamForRead();

//create a video file
StorageFolder folder = KnownFolders.VideosLibrary;
StorageFile video = await folder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
                    
System.IO.Stream outstream = await video.OpenStreamForWriteAsync();
const int bufferSize = 4096;
while (inputStream.Position < inputStream.Length)//inputStream has canSeek= false so i receive an exception
{
    byte[] buffer = new byte[bufferSize];
    int amountRead = inputStream.Read(buffer, 0, bufferSize);
    outstream.Write(buffer, 0, amountRead);
  
}
outstream.Flush();

推荐答案

我建议您使用DataReader和DataWriter来读取和写入数据。

I suggest you using the DataReader and DataWriter to read and write the steam.

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Web.Http;
using System.Threading;
using System;
using Windows.Storage.Streams;

namespace CommonLab
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private HttpClient httpClient;

        private CancellationTokenSource cts;

        private const uint BUFFER_SIZE = 64;

        public MainPage()
        {
            this.InitializeComponent();

            cts = new CancellationTokenSource();

            httpClient = new HttpClient();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            Uri uri = new Uri("http://www.google.com");

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);

            HttpResponseMessage response = await httpClient.SendRequestAsync(
                    request,
                    HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token);

            var stream = await response.Content.ReadAsInputStreamAsync();

            //in your case, reapleace the memory stream by file stream 
            var outputStream = new InMemoryRandomAccessStream();

            using (var dataWriter = new DataWriter(outputStream.GetOutputStreamAt(0)))
            {
                using (var dataReader = new DataReader(stream))
                {
                    while (true)
                    {
                        var bytesRead = await dataReader.LoadAsync(BUFFER_SIZE);

                        var buffer = dataReader.ReadBuffer(Math.Min(bytesRead, BUFFER_SIZE));

                        dataWriter.WriteBuffer(buffer);

                        if (bytesRead < BUFFER_SIZE)
                        {
                            break;
                        }

                        await dataWriter.StoreAsync();

                        await dataWriter.FlushAsync();
                    }

                    dataWriter.DetachStream();

                    // verify the output
                    var reader = new DataReader(outputStream.GetInputStreamAt(0));
                    var size = await reader.LoadAsync((uint)outputStream.Size);
                    var html = reader.ReadString(size);
                }
            }
        }
    }
}

问候,

Jeffrey


这篇关于通过使用http请求检索的流保存大文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆