Vb.net 为什么我必须将FTP流复制到另一个变量以将其返回到调用方法?
我正在构建一些代码,以便通过Vb.net 为什么我必须将FTP流复制到另一个变量以将其返回到调用方法?,vb.net,ftp,ftpwebrequest,downloadfile,getresponsestream,Vb.net,Ftp,Ftpwebrequest,Downloadfile,Getresponsestream,我正在构建一些代码,以便通过FtpWebRequest下载图像。当我收集对下载文件流的响应时,我能够将内存中的图像返回到调用函数的唯一方法是使用MyResponseStream.CopyTo(MyMemoryStream)然后返回MyMemoryStream。这是可行的,但我不明白为什么我需要在内存中创建一个图像的两个副本(可能非常大)。当我试图直接返回MyResponseStream时,代码只是挂在空间的某个地方,我必须停止调试器 为什么我不能这样做?:在下面的代码中返回MyResponseS
FtpWebRequest
下载图像。当我收集对下载文件流的响应时,我能够将内存中的图像返回到调用函数的唯一方法是使用MyResponseStream.CopyTo(MyMemoryStream)
然后返回MyMemoryStream
。这是可行的,但我不明白为什么我需要在内存中创建一个图像的两个副本(可能非常大)。当我试图直接返回MyResponseStream
时,代码只是挂在空间的某个地方,我必须停止调试器
为什么我不能这样做?:在下面的代码中返回MyResponseStream
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
Imports System.IO
导入系统.Net
公共函数GetJpgImage(ByVal ImageID为整数)
'在memoryStream中从服务器返回图像文件
'代码来自:http://www.dreamincode.net/forums/topic/77912-ftp-download-delete/
'生成请求的文件字符串
将MyRequestedFile设置为字符串
MyRequestedFile=ImageID.ToString&“.jpg”
'创建FTP请求
Dim ftpRequest作为FtpWebRequest=DirectCast(WebRequest.Create(“ftp://mysite.com/www/downloads/“&MyRequestedFile),FtpWebRequest)
ftpRequest.Credentials=newnetworkcredential(“mySpecialUser”、“superSecretPwd”)
ftpRequest.UseBinary=True
ftpRequest.KeepAlive=False“没有僵尸”
'检查文件是否存在(叹息…以后再做)
'选择下载方法
ftpRequest.Method=WebRequestMethods.Ftp.DownloadFile
'响应设置
将MyMemoryStream暗显为新MemoryStream
Dim FTPResponse作为FtpWebResponse=DirectCast(ftpRequest.GetResponse,FtpWebResponse)
'发送请求并返回memoryStream
使用MyResponseStream作为IO.Stream=FTPResponse.GetResponseStream
'复制到内存流,以便关闭FTP连接
MyResponseStream.CopyTo(MyMemoryStream)“为什么不将函数声明为:
Public Function GetJpgImage(ByVal ImageID As Integer) as MemoryStream
如果您正在返回:
Return MyMemoryStream
编辑:尝试将return语句更改为不使用,仅用于测试。
如果在using语句中包含return,这并不重要
但我只是想确定一下。因为你所经历的行为也不正常
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
事实上,我最初确实是这样声明的,这似乎对这个问题没有什么影响。最后,我将再次添加这一点。为了确定,我在函数declare中使用作为MemoryStream
以及作为IO.Stream
进行了测试。当我尝试返回MyResponseStream
时仍挂起。已更新我的答案。我只是想帮你,因为这真的很奇怪。感谢你的想法,让我在这里澄清一下。问题中的代码作为posted是有效的,但我试图弄清楚为什么我必须使用CopyTo()
方法才能返回流。我尝试使用DIM语句而不是使用结构,但仍然得到了相同的结果,因此我不认为使用
方法是问题所在。虽然我没有直接尝试这个想法,但我已经有效地测试了这个变体,它的工作原理和把它留在里面一样。基于同样的想法,我不能在using块之外返回MyResponseStream
,因为那时它已经被释放了。您正在返回MyMemoryStream no Response。在using语句MyMemoryStream工作之前声明了谁,它将返回我需要的内容。但是我不喜欢使用CopyTo()
方法。我在这里尝试优化,因为我不想在内存中有两个相同图像的副本。我宁愿直接返回MyResponseStream
,但这不起作用,我不明白为什么。
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);
}