使用 FTP FileUpload 上传的零大小文件
我最近阅读了大量关于 ASP.NET 中 FTP 上传的文章,它们似乎都很有道理,但每次我尝试实现它们时,我要么上传一个空文件,要么根本没有文件。以下是我读过的一些文章:
- 管理来自 ASP 的 FTP 传输.NET 网页 作者:John Peterson
- 文件上传控件没有给出完整路径......帮助!!!!
- 如何:使用 FileUpload Web 服务器控件上传文件< /a>
它们都是很棒的文章,但就像我说的,有问题:(
我确切地知道问题是什么,但我不知道如何解决它。我可以从 FileUpload 控件传递文件名,但是出于安全考虑,该路径不存在。但是,StreamReader 对象需要上传文件的完全限定路径,所以我到底如何得到它
?使用我上面链接的约翰彼得森的例子。这是代码:
Protected Sub btnUploadFile_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
Dim myStreamWriter As StreamWriter
myFtpWebRequest = WebRequest.Create("ftp://ftp_server_name/filename.ext")
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
myStreamWriter = New StreamWriter(myFtpWebRequest.GetRequestStream())
'IT BREAKS HERE BECAUSE THE CLIENT PATH IS WRONG!!
myStreamWriter.Write(New StreamReader(Server.MapPath("filename.ext")).ReadToEnd)
myStreamWriter.Close()
myFtpWebResponse = myFtpWebRequest.GetResponse()
myFtpWebResponse.Close()
End Sub
看到了吗?上传的文件中没有数据:(
现在我最新的实现看起来像这样,但是上传的文件多了比源更大,而且严重损坏,我到底做错了什么?我已经花了两天时间了,
Protected Sub btnUploadFile2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
filename = Path.GetFileName(FileUpload1.FileName)
myFtpWebRequest = CType(WebRequest.Create(ftpServer + ftpPath + filename), FtpWebRequest)
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
'NEW APPROACH USING THE STREAM OF THE FILE FROM THE FileUpload Control
'CORRECT BYTE LENGTH - in sourceStream.BaseStream
Dim sourceStream As New StreamReader(FileUpload1.FileContent)
'WRONG BYTE LENGTH - in sourceStream.ReadToEnd()
Dim fileContents As Byte() = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd())
sourceStream.Close()
myFtpWebRequest.ContentLength = fileContents.Length
Dim requestStream As Stream = myFtpWebRequest.GetRequestStream()
requestStream.Write(fileContents, 0, fileContents.Length)
requestStream.Close()
myFtpWebResponse = CType(myFtpWebRequest.GetResponse(), FtpWebResponse)
myFtpWebResponse.Close()
End Sub
非常感谢 Adam Maras 的惊人回答,我会留下我的错误。这里是为了其他人受益于找到此线程的人;)
I've been reading gobs of articles on FTP upload in ASP.NET recently and they all seem to make sense, but every time I've tried implementing them I either get an empty file uploaded, or no file at all. Here are some of the articles I've been reading:
- Managing FTP Transfers from an ASP.NET Web Page By John Peterson
- FileUpload Control Doesn’t Give Full Path….HELP!!!!
- How to: Upload Files with the FileUpload Web Server Control
They're all great articles, but like I said, having issues :(
I know exactly what the problem is but I don't know how to fix it. I can pass the file name from the FileUpload control, but the path does not exist for security concerns. However, the StreamReader object requires the fully qualified path of the file to be uploaded, so how the heck do I get that? I'm at my wits end! >.<
Let's use the example by John Peterson that I linked above. Here's the code:
Protected Sub btnUploadFile_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
Dim myStreamWriter As StreamWriter
myFtpWebRequest = WebRequest.Create("ftp://ftp_server_name/filename.ext")
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
myStreamWriter = New StreamWriter(myFtpWebRequest.GetRequestStream())
'IT BREAKS HERE BECAUSE THE CLIENT PATH IS WRONG!!
myStreamWriter.Write(New StreamReader(Server.MapPath("filename.ext")).ReadToEnd)
myStreamWriter.Close()
myFtpWebResponse = myFtpWebRequest.GetResponse()
myFtpWebResponse.Close()
End Sub
See? No data in the uploaded file :(
Now my latest implementation looks like this, but the uploaded file is much larger than the source, and corrupted. Seriously, what the heck am I doing wrong? I've been two LONG days at this, grrr...
Protected Sub btnUploadFile2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim myFtpWebRequest As FtpWebRequest
Dim myFtpWebResponse As FtpWebResponse
filename = Path.GetFileName(FileUpload1.FileName)
myFtpWebRequest = CType(WebRequest.Create(ftpServer + ftpPath + filename), FtpWebRequest)
myFtpWebRequest.Method = WebRequestMethods.Ftp.UploadFile
myFtpWebRequest.UseBinary = True
'NEW APPROACH USING THE STREAM OF THE FILE FROM THE FileUpload Control
'CORRECT BYTE LENGTH - in sourceStream.BaseStream
Dim sourceStream As New StreamReader(FileUpload1.FileContent)
'WRONG BYTE LENGTH - in sourceStream.ReadToEnd()
Dim fileContents As Byte() = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd())
sourceStream.Close()
myFtpWebRequest.ContentLength = fileContents.Length
Dim requestStream As Stream = myFtpWebRequest.GetRequestStream()
requestStream.Write(fileContents, 0, fileContents.Length)
requestStream.Close()
myFtpWebResponse = CType(myFtpWebRequest.GetResponse(), FtpWebResponse)
myFtpWebResponse.Close()
End Sub
Thanks ever so much to Adam Maras for the amazing answer. I'll leave my blunders here for others to benefit who find this thread ;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,如果您要像这样使用 ASP.NET,您必须通过网络服务器上传。如果不在客户端浏览器上安装插件或使用 ActiveX 控件(或类似控件),您绝对无法直接从客户端计算机上传到 FTP 服务器。
我假设您正在上传二进制文件;如果是这种情况,您使用 StreamReader 和 StreamWriter 的方式可能会损坏文件的二进制内容。相反,我们可以使用
Stream.CopyTo
将数据逐字从一个流移动到另一个流的方法。我已经修改了您的方法以使用此模式:
First of all, you must upload through the web server if you're going to use ASP.NET like this. Without installing a plugin on the client's browser or using an ActiveX control (or similar) you absolutely cannot upload directly from the client machine to the FTP server.
I assume you're uploading binary files; if that's the case, the way you're using
StreamReader
s andStreamWriter
s could be corrupting the binary contents of the file. Instead, we can use theStream.CopyTo
method to move the data verbatim from one stream to the other.I've modified your method to use this pattern instead:
FileUpload.SaveAs()
方法保存到Web 服务器的本地文件系统,并且无法写入 URI 或 FTP 站点。为此,您需要创建一个WebRequest
。请参阅此处有关 FileUpload 控件的 MSDN 参考: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.fileupload.saveas.aspx
以及此处 WebRequest 的 FTP 使用:http://msdn.microsoft.com/en-us/library/ms229715.aspx
请注意 FileUpload 文档中给出的示例保存到 c:\temp\uploadedfiles。我建议您使用 Path.GetTempFileName() 来代替,因为这保证为您提供一个无论您在什么环境下都可以始终写入的文件。
The
FileUpload.SaveAs()
method saves to the Web server's local file system, and can't write to a URI or FTP site. To do that, you'll need to create aWebRequest
.See the MSDN reference for the FileUpload control here: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.fileupload.saveas.aspx
and for the FTP use of a WebRequest here: http://msdn.microsoft.com/en-us/library/ms229715.aspx
Note the example given in the FileUpload documentation saves to c:\temp\uploadedfiles. I'd suggest you use
Path.GetTempFileName()
instead as this is guaranteed to give you a file that can always be written no matter what environment you're under.数据会被损坏,因为您将文件当作文本来读取,但事实并非如此。
使用
BinaryReader
而不是StreamReader
,以便您可以直接以字节形式读取数据:The data gets corrupted because you are reading the file as if it was text, but it's not.
Use a
BinaryReader
instead of aStreamReader
so that you can read the data as bytes directly: