C# 将 IFormFile 读入 byte[]
C# read IFormFile into byte[]
我正在尝试读取从 HTTP POST 请求收到的 IFormFile
,如下所示:
public async Task<ActionResult> UploadDocument([FromForm]DataWrapper data)
{
IFormFile file = data.File;
string fileName = file.FileName;
long length = file.Length;
if (length < 0)
return BadRequest();
using FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate);
byte[] bytes = new byte[length];
fileStream.Read(bytes, 0, (int)file.Length);
...
}
但是出了点问题,在这一行执行之后:
fileStream.Read(bytes, 0, (int)file.Length);
bytes
的所有元素均为零。
此外,在我的 Visual Studio 项目中创建了同名文件,我不希望这种情况发生。
您无法像打开磁盘上的文件那样打开 IFormFile
。您必须改用 IFormFile.OpenReadStream()
。 Docs here
public async Task<ActionResult> UploadDocument([FromForm]DataWrapper data)
{
IFormFile file = data.File;
long length = file.Length;
if (length < 0)
return BadRequest();
using var fileStream = file.OpenReadStream();
byte[] bytes = new byte[length];
fileStream.Read(bytes, 0, (int)file.Length);
}
fileStream.Read(bytes, 0, (int)file.Length);
之所以看起来是空的,是因为它确实是。 IFormFile.Filename
是请求给出的文件名,磁盘上不存在。
您的代码的意图似乎是写入 FileStream,而不是字节缓冲区。它实际上所做的是创建一个新的空文件并从中读入一个已经清除的缓冲区。上传的文件从未使用过。
写入文件
如果真的要保存文件,可以使用CopyTo :
using(var stream = File.Create(Path.Combine(folder_I_Really_Want,file.FileName))
{
file.CopyTo(stream);
}
如果您想将上传的文件读入缓冲区而不保存到磁盘,请使用 MemoryStream。这只是 byte[]
缓冲区上的 Stream API 缓冲区。您不必指定大小,但随着内部缓冲区的增长,这会减少重新分配。
读入byte[]
通过 MemoryStream 读入 byte[] 本质上是一样的:
var stream = new MemoryStream(file.Length);
file.CopyTo(stream);
var bytes=stream.ToArray();
问题是您正在根据模型中的文件名打开一个新的文件流,该文件名将是用户在上传时选择的文件名。您的代码将创建一个具有该名称的新空文件,这就是您在文件系统中看到该文件的原因。然后您的代码从该空文件中读取字节。
您需要使用 IFormFile.OpenReadStream 方法或其中一种 CopyTo 方法从流中获取实际数据。
然后您将该数据写入您文件系统上的文件并使用您想要的名称。
var filename ="[Enter or create name for your file here]";
using (FileStream fs = new FileStream(filename, FileMode.OpenOrCreate))
//Create the file in your file system with the name you want.
{
using (MemoryStream ms = new MemoryStream())
{
//Copy the uploaded file data to a memory stream
file.CopyTo(ms);
//Now write the data in the memory stream to the new file
fs.Write(ms.ToArray());
}
}
我正在尝试读取从 HTTP POST 请求收到的 IFormFile
,如下所示:
public async Task<ActionResult> UploadDocument([FromForm]DataWrapper data)
{
IFormFile file = data.File;
string fileName = file.FileName;
long length = file.Length;
if (length < 0)
return BadRequest();
using FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate);
byte[] bytes = new byte[length];
fileStream.Read(bytes, 0, (int)file.Length);
...
}
但是出了点问题,在这一行执行之后:
fileStream.Read(bytes, 0, (int)file.Length);
bytes
的所有元素均为零。
此外,在我的 Visual Studio 项目中创建了同名文件,我不希望这种情况发生。
您无法像打开磁盘上的文件那样打开 IFormFile
。您必须改用 IFormFile.OpenReadStream()
。 Docs here
public async Task<ActionResult> UploadDocument([FromForm]DataWrapper data)
{
IFormFile file = data.File;
long length = file.Length;
if (length < 0)
return BadRequest();
using var fileStream = file.OpenReadStream();
byte[] bytes = new byte[length];
fileStream.Read(bytes, 0, (int)file.Length);
}
fileStream.Read(bytes, 0, (int)file.Length);
之所以看起来是空的,是因为它确实是。 IFormFile.Filename
是请求给出的文件名,磁盘上不存在。
您的代码的意图似乎是写入 FileStream,而不是字节缓冲区。它实际上所做的是创建一个新的空文件并从中读入一个已经清除的缓冲区。上传的文件从未使用过。
写入文件
如果真的要保存文件,可以使用CopyTo :
using(var stream = File.Create(Path.Combine(folder_I_Really_Want,file.FileName))
{
file.CopyTo(stream);
}
如果您想将上传的文件读入缓冲区而不保存到磁盘,请使用 MemoryStream。这只是 byte[]
缓冲区上的 Stream API 缓冲区。您不必指定大小,但随着内部缓冲区的增长,这会减少重新分配。
读入byte[]
通过 MemoryStream 读入 byte[] 本质上是一样的:
var stream = new MemoryStream(file.Length);
file.CopyTo(stream);
var bytes=stream.ToArray();
问题是您正在根据模型中的文件名打开一个新的文件流,该文件名将是用户在上传时选择的文件名。您的代码将创建一个具有该名称的新空文件,这就是您在文件系统中看到该文件的原因。然后您的代码从该空文件中读取字节。
您需要使用 IFormFile.OpenReadStream 方法或其中一种 CopyTo 方法从流中获取实际数据。
然后您将该数据写入您文件系统上的文件并使用您想要的名称。
var filename ="[Enter or create name for your file here]";
using (FileStream fs = new FileStream(filename, FileMode.OpenOrCreate))
//Create the file in your file system with the name you want.
{
using (MemoryStream ms = new MemoryStream())
{
//Copy the uploaded file data to a memory stream
file.CopyTo(ms);
//Now write the data in the memory stream to the new file
fs.Write(ms.ToArray());
}
}