views:

275

answers:

2

Hello, I'm trying to use a local c# app to pull some images off a website to files on my local machine. I'm using the code listed below. I've tried both ASCII encoding and UTF8 encoding but the final file is not an correct. Does anyone see what I'm doing wrong? The url is active and correct and show the image just fine when I put the address in my browser.

Thanks, Steve

    private void button1_Click(object sender, EventArgs e)
    {
        HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");

        // returned values are returned as a stream, then read into a string
        String lsResponse = string.Empty;
        HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse();
        using (StreamReader lxResponseStream = new StreamReader(lxResponse.GetResponseStream()))
        {
            lsResponse = lxResponseStream.ReadToEnd();
            lxResponseStream.Close();
        }

        byte[] lnByte = System.Text.UTF8Encoding.UTF8.GetBytes(lsResponse);

        System.IO.FileStream lxFS = new FileStream("34891.jpg", FileMode.Create);
        lxFS.Write(lnByte, 0, lnByte.Length);
        lxFS.Close();

        MessageBox.Show("done");
    }
+1  A: 

nice image :D

try using the following code:

you needed to use a binaryreader, 'cause an image file is binary data and thus not encoded in utf or ascii

edit: using'ified

        HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");

        // returned values are returned as a stream, then read into a string
        String lsResponse = string.Empty;
        using (HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse())
        {
            using (BinaryReader reader = new BinaryReader(lxResponse.GetResponseStream()))
            {
                Byte[] lnByte = reader.ReadBytes(1 * 1024 * 1024 * 10);

                using (FileStream lxFS = new FileStream("34891.jpg", FileMode.Create))
                {
                    lxFS.Write(lnByte, 0, lnByte.Length);
                }
            }
        }

        MessageBox.Show("done");
henchman
-1: I know you're just changing his provided code, but you should really improve it to not have resource leaks. Show him where to put the `using` blocks, and I'll remove my downvote.
John Saunders
I like using the .Close method instead of using blocks. According to msdn: This implementation of Close calls the Dispose method passing a true value. So we should be fine according to ressource leaks. are using blocks safer or have advantage over .Close()? (edit: forgot one close)
henchman
@henchman: a `using` block ensures that `Dispose` will be called, even in the presence of an unhandled exception. It's a bad habit not to use them in almost all appropriate cases (where you create an instance of a class implementing `IDisposable`, only assign it to local variables, and don't return it from the method that created it, and when it's not a WCF proxy instance). If you always use it, you won't forget it once or twice.
John Saunders
john ftw :-)changing code so no one gets my bad habbits..
henchman
thanks for the answers guys. I think John's right about the using blocks, even with the .close method. I think that does the dispose right away instead of disposing at the end of the routine when the variable falls out of scope. I also think I'll work on the ReadBytes part of the routine to read the stream in chunks until it ends instead of presuming a 10MB limit.
Steve Brownell
Please let us know about your solution for the 10MB limit - i couldn't find one for this type of reader/stream-combination. Stream.Length is not usable. Using-blocks also look nicer than .Close(), though it can be interesting when some more blocks will be aggregated regarding the indentation :-)
henchman
+1  A: 

Okay, here's the final answer. It uses a memorystream as a way to buffer the data from the reaponsestream.

    private void button1_Click(object sender, EventArgs e)
    {
        byte[] lnBuffer;
        byte[] lnFile;

        HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");
        using (HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse())
        {
            using (BinaryReader lxBR = new BinaryReader(lxResponse.GetResponseStream()))
            {
                using (MemoryStream lxMS = new MemoryStream())
                {
                    lnBuffer = lxBR.ReadBytes(1024);
                    while (lnBuffer.Length > 0)
                    {
                        lxMS.Write(lnBuffer, 0, lnBuffer.Length);
                        lnBuffer = lxBR.ReadBytes(1024);
                    }
                    lnFile = new byte[(int)lxMS.Length];
                    lxMS.Position = 0;
                    lxMS.Read(lnFile, 0, lnFile.Length);
                    lxMS.Close();
                    lxBR.Close();
                }
            }
            lxResponse.Close();
        }

        using (System.IO.FileStream lxFS = new FileStream("34891.jpg", FileMode.Create))
        {
            lxFS.Write(lnFile, 0, lnFile.Length);
            lxFS.Close();
        }
        MessageBox.Show("done");
    }
Steve Brownell
oh yeah... forgot to remove the close methods now that I'm using the using blocks.
Steve Brownell