0

The program that uses this function is receiving files of multiple types and sizes from another PC. It has been working well but when the files' size exceeds about 100MB I run out of memory. I need to modify the receiving code so that it saves the incomplete file to the hard drive instead of the memory as it is being read from the stream. Kind of like how Firefox downloads things if you watch it. It makes a .PART file and it increases in size until it's done downloading.

I'm not sure how to do this with the code I have...Any help is appreciated.

Here's the code:

public object Receive()
        {
            MemoryStream MS;
            BinaryFormatter BF = new BinaryFormatter();

            byte[] Buffer = new byte[8];                        //First 8 bytes are the size of the data
            NetStream.Read(Buffer, 0, 8);                       //Read them
            Buffer = new byte[BitConverter.ToInt32(Buffer, 0)]; //Set the buffer accordingly

            int BytesRecieved = 0;

            while (BytesRecieved != Buffer.Length)
            {
                try
                {
                    BytesRecieved = BytesRecieved + NetStream.Read(Buffer, BytesRecieved, 1024); //Read a kilobyte to the buffer at a time
                }

                catch (ArgumentOutOfRangeException) //There's less than 1 KB left to read
                {
                    BytesRecieved = BytesRecieved + NetStream.Read(Buffer, BytesRecieved, Buffer.Length - BytesRecieved);
                }
            }

            MS = new MemoryStream(Buffer);
            return BF.Deserialize(MS);
        }

Edited by WildBamaBoy: removed gui code

2
Contributors
1
Reply
2
Views
5 Years
Discussion Span
Last Post by oredigger
0

Try using a FileStream instead of a memory stream. Then when you read the next 1024 bytes, write them to the file.

int bytesReceived = 0;
int bytesWritten = 0;

FileStream _myFileStream = new FileStream("myData.part", FileMode.Create);

while (BytesReceived != Buffer.Length)
{
    try
    {
        BytesRecieved = BytesRecieved + NetStream.Read(Buffer, BytesRecieved, 1024); //Read a kilobyte to the buffer at a time
    }
 
    catch (ArgumentOutOfRangeException) //There's less than 1 KB left to read
    {
        BytesRecieved = BytesRecieved + NetStream.Read(Buffer, BytesRecieved,  Buffer.Length - BytesRecieved);
    }

    _myFileStream.Write(Buffer, bytesWritten, BytesReceived);
    bytesWritten = BytesReceived;
}
_myFileStream.Flush();

You don't need the Write call inside the try/catch block because it will be the same regardless of if there was less than 1KB left to read or not.

Then once it's written you should be able to deserialize it.

return BF.Deserialize(_myFileStream);

Haven't tried this, just brainstorming!

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.