【问题标题】:C# read IFormFile into byte[]C# 将 IFormFile 读入 byte[]
【发布时间】:2019-11-22 08:42:27
【问题描述】:

我正在尝试读取从 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 项目中创建的,我不希望发生这种情况。

【问题讨论】:

  • 您是要写入文件还是直接读取缓冲区?您的代码正在创建一个空文件并从中读取。它从不尝试读取上传的文件

标签: c# filestream iformfile


【解决方案1】:

您无法像打开磁盘上的文件一样打开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 是请求给出的文件名,在磁盘上不存在。

【讨论】:

    【解决方案2】:

    您的代码的意图似乎是写入 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();
    

    【讨论】:

      【解决方案3】:

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

      您需要使用 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());
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多