在ASP.NET Web Api C#中通过流发送和接收大型文件

我正在开发一个项目,我需要通过流从客户端向服务器发送大型音频文件。 我正在使用ASP.NET Web Api在客户端和服务器之间进行通信。 我的客户端有一个“SendFile”方法,我相信它工作正常,但我不知道如何让我的服务器接收我通过流发送的数据。 到目前为止,我的客户端代码如下所示:

private const int MAX_CHUNK_SIZE = (1024 * 5000); private HttpWebRequest webRequest = null; private FileStream fileReader = null; private Stream requestStream = null; public bool SendAudio(string uri, string file) { byte[] fileData; fileReader = new FileStream(file, FileMode.Open, FileAccess.Read); webRequest = (HttpWebRequest)WebRequest.Create(uri); webRequest.Method = "POST"; webRequest.ContentLength = fileReader.Length; webRequest.Timeout = 600000; webRequest.Credentials = CredentialCache.DefaultCredentials; webRequest.AllowWriteStreamBuffering = false; requestStream = webRequest.GetRequestStream(); long fileSize = fileReader.Length; long remainingBytes = fileSize; int numberOfBytesRead = 0, done = 0; while (numberOfBytesRead < fileSize) { SetByteArray(out fileData, remainingBytes); done = WriteFileToStream(fileData, requestStream); numberOfBytesRead += done; remainingBytes -= done; } fileReader.Close(); return true; } public int WriteFileToStream(byte[] fileData, Stream requestStream) { int done = fileReader.Read(fileData, 0, fileData.Length); requestStream.Write(fileData, 0, fileData.Length); return done; } private void SetByteArray(out byte[] fileData, long bytesLeft) { fileData = bytesLeft < MAX_CHUNK_SIZE ? new byte[bytesLeft] : new byte[MAX_CHUNK_SIZE]; } 

我的服务器看起来像这样:

  [HttpPost] [ActionName("AddAudio")] public async Task AddAudio([FromUri]string name) { try { isReceivingFile = true; byte[] receivedBytes = await Request.Content.ReadAsByteArrayAsync(); if (WriteAudio(receivedBytes, name) == true) { isReceivingFile = false; return Ok(); } else { isReceivingFile = false; return BadRequest("ERROR: Audio could not be saved on server."); } } catch (Exception ex) { isReceivingFile = false; return BadRequest("ERROR: Audio could not be saved on server."); } } public bool WriteAudio(byte[] receivedBytes, string fileName) { string file = Path.Combine(@"C:\Users\username\Desktop\UploadedFiles", fileName); using (FileStream fs = File.Create(file)) { fs.Write(receivedBytes, 0, receivedBytes.Length); } return true; } 

服务器代码具有我为其编写的原始代码,然后决定尝试使用流。 如果我发送一个小文件(30 MB以下),服务器代码仍然有效,但如果我发送一个大文件,我的服务器会出现“outofmemoryexception”。 我无法弄清楚如何让服务器通过流接收数据。 在我寻找解决方案的过程中,我遇到了很多关于套接字和TCPClient的例子,但这不是我们想要在这个项目上做的。 请帮忙吗?

如果我发送一个大文件,我的服务器会出现“outofmemoryexception”

好吧,它正在将整个流读入内存:

 byte[] receivedBytes = await Request.Content.ReadAsByteArrayAsync(); 

您要做的是流从一个位置复制到另一个位置, 不是一次将其全部加载到内存中。 像这样的东西应该工作:

 [HttpPost] [ActionName("AddAudio")] public async Task AddAudio([FromUri]string name) { try { string file = Path.Combine(@"C:\Users\username\Desktop\UploadedFiles", fileName); using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true)) { await Request.Context.CopyToAsync(fs); } return Ok(); } catch (Exception ex) { return BadRequest("ERROR: Audio could not be saved on server."); } }