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

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!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.