文件较大时如何在WebAPI中读取文件块

时间:2019-02-19 19:01:22

标签: c# asp.net .net asp.net-web-api asp.net-web-api2

我有一个大文件,我想将其发送到Web API,然后再将其发送到Amazon。由于文件很大,因此我想按块将文件发送到亚马逊。 因此,如果我有1 GB的文件,我希望我的API接收20 MB的块中的文件,以便可以将其发送到Amazon,然后再次接收20 MB的块。这怎么做。以下是我的尝试。

public async Task<bool> Upload()
{
    var fileuploadPath = ConfigurationManager.AppSettings["FileUploadLocation"];
    var provider = new MultipartFormDataStreamProvider(fileuploadPath);
    var content = new StreamContent(HttpContext.Current.Request.GetBufferlessInputStream(true));
    // Now code below writes to a folder, but I want to make sure I read it as soon as I receive some chunk
    await content.ReadAsMultipartAsync(provider);
    return true;
}

伪代码:

While (await content.ReadAsMultipartAsync(provider) == 20 MB chunk)
{
  //Do something
  // Then again do something with rest of chunk and so on.
}

文件最大为1 GB。

到目前为止,此行代码将发送整个文件:

await content.ReadAsMultipartAsync(provider);

我在这里迷路了,请帮助我。我想要的只是接收小块文件并进行处理。

P.S:我正在从邮递员以MultiPart / Form-Data的形式发送文件进行测试。

enter image description here

尝试2:

var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
foreach (var content in filesReadToProvider.Contents)
{
   var stream = await content.ReadAsStreamAsync();
   using (StreamReader sr = new StreamReader(stream))
   {
       string line = "";
       while ((line = sr.ReadLine()) != null)
       {
           using (MemoryStream outputStream = new MemoryStream())
           using (StreamWriter sw = new StreamWriter(outputStream))
           {
               sw.WriteLine(line);
               sw.Flush();
               // Do Something
           }
       }
   }
}

1 个答案:

答案 0 :(得分:0)

没有时间进行测试,但是ReadBlock方法似乎是您要使用的方法。 应该看起来像我下面的内容,但是它假定您所有其他代码都很好,并且您只需要缓冲方面的帮助即可。这是一个“阻止”读取操作,但是还有一个ReadBlockAsync方法可返回Task。

const int bufferSize= 1024;
var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
foreach (var content in filesReadToProvider.Contents)
{
    var stream = await content.ReadAsStreamAsync();
    using (StreamReader sr = new StreamReader(stream))
    {
        int bytesRead;
        char[] buffer = new char[bufferSize];
        while ((bytesRead = sr.ReadBlock(buffer, 0, bufferSize)) > 0)
        {
              // Do something with the first <bytesRead> of buffer and
              // not with <bufferSize> as <bytesRead> will contain the
              // number of bytes actually read by the call to ReadBlock
        }
    }
}