Question

I am building some code to download images via FtpWebRequest. When I collect the response to the DownloadFile stream the only way that I've been able to return the image in memory to the calling function is to use MyResponseStream.CopyTo(MyMemoryStream) and then Return MyMemoryStream. This works, but I don't get why I need to create two copies of an image in memory (which could potentially be very large). When I try to return MyResponseStream directly the code just hangs out somewhere in space and I have to stop the debugger.

Why can't I just do this?: Return MyResponseStream in the code below?

Imports System.IO
Imports System.Net

Public Function GetJpgImage(ByVal ImageID As Integer)
    'returns image file from server in a memoryStream
    'code from: http://www.dreamincode.net/forums/topic/77912-ftp-download-delete/

    'build requested file string
    Dim MyRequestedFile As String
    MyRequestedFile = ImageID.ToString & ".jpg"

    'create FTP request
    Dim ftpRequest As FtpWebRequest = DirectCast(WebRequest.Create("ftp://mysite.com/www/downloads/" & MyRequestedFile), FtpWebRequest)
    ftpRequest.Credentials = New NetworkCredential("mySpecialUser", "superSecretPwd")
    ftpRequest.UseBinary = True 
    ftpRequest.KeepAlive = False 'No Zombies

    'check if file exists (sigh... do it later)

    'select download method
    ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile

    'setup for response
    Dim MyMemoryStream As New MemoryStream
    Dim FTPResponse As FtpWebResponse = DirectCast(ftpRequest.GetResponse, FtpWebResponse)

    'send request and return memoryStream
    Using MyResponseStream As IO.Stream = FTPResponse.GetResponseStream
        'copy to memory stream so we can close the FTP connection
        MyResponseStream.CopyTo(MyMemoryStream)  '<== Why God? Why?
        'close FTP stream
        MyResponseStream.Close()
        'gimme my data!
        Return MyMemoryStream
    End Using
End Function

It doesn't have anything to do with MyResponseStream being in a Using statement (I tried it). VS 2012, Win8.

Was it helpful?

Solution

Why dont you have the function declared like:

Public Function GetJpgImage(ByVal ImageID As Integer) as MemoryStream

if you are returning:

 Return MyMemoryStream

EDIT: Try changing the return statement out of the using, Just for testing. It doesn't really matter if you include your return inside the using statement but just to be sure. Because the behaviour you are experiencing is not normal as well

 Using MyResponseStream As IO.Stream = FTPResponse.GetResponseStream
    'copy to memory stream so we can close the FTP connection
    MyResponseStream.CopyTo(MyMemoryStream)  '<== Why God? Why?
    'close FTP stream
    MyResponseStream.Close()
    'gimme my data!

End Using

Return MyMemoryStream

EDIT2:. If you dont want to use the Copy To, try to read the stream into the memoryStream using the traditional way:

MemoryStream memStream;
using (Stream response = request.GetResponseStream()) {
    memStream = new MemoryStream();

    byte[] buffer = new byte[1024];
    int byteCount;
    do {
        byteCount = stream.Read(buffer, 0, buffer.Length);
        memStream.Write(buffer, 0, byteCount);
    } while (byteCount > 0);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top