添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am trying to read an IFormFile received from a HTTP POST request like this:

 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);

but something is wrong, after this line executes:

fileStream.Read(bytes, 0, (int)file.Length);

all of the elements of bytes are zero.

Also, the file with the same name is created in my Visual Studio project, which I would prefer not to happen.

Are you trying to write to a file or read directly into a buffer? Your code is creating an empty file and reading from it. It never tries to read the uploaded file – Panagiotis Kanavos Nov 22, 2019 at 8:58

You can't open an IFormFile the same way you would a file on disk. You'll have to use IFormFile.OpenReadStream() instead. 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);

The reason that fileStream.Read(bytes, 0, (int)file.Length); appears to be empty is, because it is. The IFormFile.Filename is the name of the file given by the request and doesn't exist on disk.

Your code's intent seems to be to write to a FileStream, not a byte buffer. What it actually does though, is create a new empty file and read from it into an already cleared buffer. The uploaded file is never used.

Writing to a file

If you really want to save the file, you can use CopyTo :

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

If you want to read from the uploaded file into a buffer without saving to disk, use a MemoryStream. That's just a Stream API buffer over a byte[] buffer. You don't have to specify the size but that reduces reallocations as the internal buffer grows.

Reading into byte[]

Reading into a byte[] through MemoryStream is essentially the same :

var stream = new MemoryStream(file.Length);
file.CopyTo(stream);
var bytes=stream.ToArray();
                Small problem here: file.Length is a long, but MemoryStream can only take an int in the constructor. Instead, use var stream = new MemoryStream((int)file.Length); This will throw an OverflowException if length is greater than int.MaxValue, but MemoryStream can't handle files that large anyway.
– Doug
                May 16, 2022 at 14:58
                Loading 100MB into a memory stream is a bad idea, much less 2GB. The web server will slow to a crawl due to memory pressure and garbage collection long before an OverflowException is thrown
– Panagiotis Kanavos
                May 16, 2022 at 16:06
                Ok, something will fail in some way, but either way, you can't compile new MemoryStream(file.Length)
– Doug
                May 16, 2022 at 17:24

The problem is that you are opening a new filestream based on the file name in your model which will be the name of the file that the user selected when uploading. Your code will create a new empty file with that name, which is why you are seeing the file in your file system. Your code is then reading the bytes from that file which is empty.

You need to use IFormFile.OpenReadStream method or one of the CopyTo methods to get the actual data from the stream.

You then write that data to your file on your file system with name you want.

        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());
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.