Converting Httppostedfilebase to byte[] : Exception_wasthrown

Asked

Viewed 1,255 times

9

Follows code:

Controller (with post action):

var file = Request.Files[0];
var bytes = ConvertTo.Bytes(file);

Convertto class :

public static byte[] Bytes(HttpPostedFileBase result)
{
    var length = result.InputStream.Length; //Length: 103050706
    MemoryStream target = new MemoryStream();
    result.InputStream.CopyTo(target); // gera problema nessa linha aqui
    byte[] data = target.ToArray(); 
    return data;
}

The file is about 98.2 MB (103,050,706 bytes) in size, 60 MB file works perfectly.

On the line: result.InputStream.CopyTo(target); get error:

System.Outofmemoryexception: 'Exception_wasthrown'

inserir a descrição da imagem aqui

Small file works well, only big file makes this problem.

Any solution for large file ?

UPDATE:

Follows code:

public static byte[] ConverToBytes(HttpPostedFileBase file)
{
    var length = file.InputStream.Length; //Length: 103050706
    byte[] fileData = null;
    using (var binaryReader = new BinaryReader(file.InputStream))
    {
        fileData = binaryReader.ReadBytes(file.ContentLength);
    }
    return fileData;
}

Code above works using BinaryReader. Because MemoryStream doesn’t work ?

  • Matheus, what are the versions of IIS, . NET Runtime and the operating environment you are using? 32 or 64 bit?

  • @Onosendai 10.0.16299.15 and Windows 10. It is 64 bits, In the project is as 32 bits.

4 answers

5


Hello, I don’t know how Memorystream works from the inside, but I did a profiler in your method and the method I did that I think would be lighter'.

By Exception the problem is lack of memory so I thought of a code that could solve the problem relying on its memory limitation.

I took the liberty of setting the parameter as Stream and not Httppostedfile to facilitate the test.

For the test I used the Rapidminer installer that has more or less 171MB.

Below is the result with your code, I do not know why you used so much memory:

public static byte[] Bytes2(Stream result)
        {
            var length = result.Length; //Length: 103050706
            MemoryStream target = new MemoryStream();
            result.CopyTo(target); // gera problema nessa linha aqui
            byte[] data = target.ToArray();
            return data;
        }

Com MemoryStream

Below I did using a code without performing the instance of Memorystream, see the difference:

    public static byte[] Bytes(Stream result)
    {
        long length = result.Length;
        byte[] data = new byte[length];
        result.Read(data, 0, (int)length); //até int.max está ok

        return data;
    }

Sem MemoyStream

Try using this second code and tell me if the problem has been solved.

  • 1

    Your code worked, no problem. You know tell me why with BinaryReader works ?

  • 1

    I’m not sure friend, I believe that Memorystream does a buffer and allots more data than necessary imagining that you will work more on it later, already Read is clearer what it does, just copies to an array.

  • 1

    I understand. How you opened this window where it shows the byte information ?

  • 2

    It is the Visual Studio Performance profiler, the most expensive verses of Visual Studio has, there you can access here: https://imgur.com/a/65VwL Ai, I use enough to see where some part of the system is slow, have other legal data as runtime in each function, etc... Then research more on it, it’s interesting.

5

The MemoryStream creates an internal buffer with a predefined value, which only grows according to the demand of the past data.

If the data you pass exceeds the size that has been pre-leased, is created a new buffer with the twice the size, that receives all the contents of the old buffer.

For example: If 128mb of memory is allocated and your file consumes more than that, the MemoryStream will attempt to allocate 256mb, and so on, by doubling the size, making the feature extremely costly.

This error may have to do with the application process settings as well, if it is in 32bits. Try to build your application with the x64.

I used as a reference this response from Soen

0

public static byte[] Bytes(HttpPostedFileBase result)
{
    byte[] data;
    using (Stream inputStream = result.InputStream)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            inputStream.CopyTo(ms);
            data = ms.ToArray();
        }
    }
    return data;
}

You urged the MemoryStream twice in MemoryStream memoryStream = inputStream as MemoryStream; and inputStream.CopyTo(memoryStream);. It was lines that didn’t make sense in the code.

Above, a MemoryStream is created in a new instance. Bytes of inputStream are copied to ms, and so, returned.

-3

A good output is to resize this image.

public ActionResult Thumbnail(string filename)
{
var img = new WebImage(filename).Resize(291, 285, false, true);
return new ImageResult(new MemoryStream(img.GetBytes()), "binary/octet-stream");
}

Webimage class documentation in MSDN.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.