4

我正在尝试读取IFormFile从 HTTP POST 请求中收到的信息,如下所示:

 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 项目中创建了具有相同名称的文件,我不希望发生这种情况。

4

3 回答 3

8

您无法以IFormFile与磁盘上文件相同的方式打开文件。你必须IFormFile.OpenReadStream()改用。文档在这里

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名称,并且在磁盘上不存在。

于 2019-11-22T08:51:21.490 回答
2

您的代码的意图似乎是写入 FileStream,而不是字节缓冲区。它实际上做的是创建一个新的空文件并将其读取到已经清除的缓冲区中。上传的文件永远不会被使用。

写入文件

如果你真的想保存文件,你可以使用CopyTo

using(var stream = File.Create(Path.Combine(folder_I_Really_Want,file.FileName))
{
    file.CopyTo(stream);
}

如果您想从上传的文件读取到缓冲区而不保存到磁盘,请使用 MemoryStream。这只是缓冲区上的 Stream APIbyte[]缓冲区。您不必指定大小,但随着内部缓冲区的增长,这会减少重新分配。

读入byte[]

通过 MemoryStream 读入 byte[] 本质上是相同的:

var stream = new MemoryStream(file.Length);
file.CopyTo(stream);
var bytes=stream.ToArray();
于 2019-11-22T08:52:39.947 回答
0

问题是您正在根据模型中的文件名打开一个新文件流,该文件名将是用户在上传时选择的文件的名称。您的代码将使用该名称创建一个新的空文件,这就是您在文件系统中看到该文件的原因。然后,您的代码正在从该文件中读取字节,该文件为空。

您需要使用 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());
            }
        }
于 2019-11-22T09:28:46.547 回答