How do i write Stream to filestream?

I am not very good with streams…

I have downloaded a file from a website into a Stream

How do i write this to the sd card or the filestream.

Stream localStream = null;

//save data to localStream  variable

 SDCard.createfile(localStream,"\\SD\\hello.jpg");


        public static void createfile(Stream sdata, string filename)
        {


            FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write);
            fileStream.Read(sdata, 0, sdata.Length); //????

            if (fileStream != null) fileStream.Close();
            fileStream = null;

        }

@ zigbox - You can read data from your local stream into a byte array and then write that byte array to the file stream.

@ Architect how do i do that?

  public static int DownloadFile(String remoteFilename, String localFilename)
        {
            string fname = localFilename.Split('\\')[localFilename.Split('\\').Length - 1];
            // Function will return the number of bytes processed
            // to the caller. Initialize to 0 here.
            int bytesProcessed = 0;
 
            // Assign values to these objects here so that they can
            // be referenced in the finally block
            Stream remoteStream = null;
            Stream localStream = null;
            WebResponse response = null;
 
            // Use a try/catch/finally block as both the WebRequest and Stream
            // classes throw exceptions upon error
            try
            {
                // Create a request for the specified remote file name
                WebRequest request = WebRequest.Create(remoteFilename);
                if (request != null)
                {
                    // Send the request to the server and retrieve the
                    // WebResponse object 
                    // request.ContentLength
                    response = request.GetResponse();
                    if (response != null)
                    {
                        // Once the WebResponse object has been retrieved,
                        // get the stream object associated with the response's data
                        remoteStream = response.GetResponseStream();
                        long total = response.ContentLength;
 
                        // Create the local file
                        localStream = File.Create(localFilename);
 
                        // Allocate a 1k buffer
 
                        byte[] buffer = new byte[1024];
                        int bytesRead;
 
                        // Simple do/while loop to read from stream until
                        // no bytes are returned
                        do
                        {
                            // Read data (up to 1k) from the stream
                            bytesRead = remoteStream.Read(buffer, 0, buffer.Length);
 
                            // Write the data to the local file
                            localStream.Write(buffer, 0, bytesRead);


                                   
                            // Increment total bytes processed
                            bytesProcessed += bytesRead;
 
                            if (onProgress != null) { onProgress(bytesProcessed, total, fname); }
                        } while (bytesRead > 0);
                    }
                }
                  
                SDCard.createfile(localStream,"\\SD\\hello.jpg"); //*******************
            }
            catch (WebException webEx)
            {
                Debug.Print("Web Exception Occured");
                if (webEx.InnerException is SocketException)
                {
                    SocketException sock = webEx.InnerException as SocketException;
                    Debug.Print("Socket error code: " + sock.ErrorCode.ToString());
                }
            }
            catch (Exception ex)
            {
                Debug.Print("Exception of type: " + ex.GetType().FullName);
                Debug.Print(ex.Message);
                if (onDownloadFinished != null) { onDownloadFinished(ex.Message); }
            }
            finally
            {
                // Close the response and streams objects here 
                // to make sure they're closed even if an exception
                // is thrown at some point
                if (response != null) response.Close();
                if (remoteStream != null) remoteStream.Close();
                if (localStream != null) localStream.Close();
            }
 
            // Return total bytes processed to caller.
            return bytesProcessed;
        }


        public static void createfile(Stream sdata, string filename)
        {


            FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write);
            fileStream.Write(sdata., 0, data.Length);

            if (fileStream != null) fileStream.Close();
            fileStream = null;

        }

Something like this (untested code):


const int BUFFER_SIZE = 1024;
        byte[] buffer = new byte[BUFFER_SIZE];
        public static void createfile(Stream sdata, string filename)
        {
    
            sdata.Seek(0,SeekOrigin.Begin);
            long remainingBytes = sdata.Length;

            FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write);

            while( remainingBytes > 0 )
            {
                int nRead = sdata.Read(buffer, 0, remainingBytes < BUFFER_SIZE ? remainingBytes : BUFFER_SIZE);

                remainingBytes -= nRead;

                fileStream.Write(buffer, 0, nRead);
            }                       
 
            if (fileStream != null) fileStream.Close();
            fileStream = null;
        }

1 Like

@ zigbox - If you don’t mind me butting in here, I have a suggestion that you are probably already aware of but I think is worth sharing anyway, just in case.

When working with objects that implement IDisposable you can use the ‘using’ statement to ensure that no matter what happens the object will be disposed.

You currently have


FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write);

// Do stuff here

if (fileStream != null) fileStream.Close();
fileStream = null;

If the code above throws an exception for any reason then the fileStream will not be closed. One solution would be to use try/finally as you have done for response, remoteStream and localStream.


FileStream fileStream = null;

try
{
    fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write);

    // Do stuff here
}
finally
{
    if (fileStream != null) fileStream.Close();
    fileStream = null;
}

But this can be handled even more elegantly with the ‘using’ statement


using(FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
    // Do stuff here
}

This will automatically call Dispose on the FileStream instance when the block ends. This is the same as calling Close. The code is cleaner and less code always reduces the risk of bugs. This can also be applied to your other variables response, remoteStream, localStream ie. anything that implements IDisposable.