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