1

我最近一直在阅读大量关于 ASP.NET 中的 FTP 上传的文章,它们似乎都很有意义,但每次我尝试实现它们时,要么上传一个空文件,要么根本没有文件。以下是我一直在阅读的一些文章:

它们都是很棒的文章,但就像我说的,有问题:(

我确切地知道问题是什么,但我不知道如何解决它。我可以从 FileUpload 控件传递文件名,但出于安全考虑,该路径不存在。但是,StreamReader 对象需要上传文件的完全限定路径,那么我到底是怎么得到的呢?我无计可施!>.<

让我们使用上面链接的 John Peterson 的示例。这是代码:

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

看?上传的文件中没有数据:(

在此处输入图像描述

现在我的最新实现看起来像这样,但是上传的文件比源文件大得多,并且已损坏。说真的,我到底做错了什么?我已经在这呆了两天了,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

非常感谢亚当马拉斯的惊人回答。我会把我的错误留在这里,让其他人受益于找到这个线程的人;)

4

3 回答 3

1

FileUpload.SaveAs()方法保存到Web 服务器的本地文件系统,不能写入 URI 或 FTP 站点。为此,您需要创建一个WebRequest.

请参阅此处的 FileUpload 控件的 MSDN 参考:http: //msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.fileupload.saveas.aspx

对于 FTP 在此处使用 WebRequest:http: //msdn.microsoft.com/en-us/library/ms229715.aspx


请注意 FileUpload 文档中给出的示例保存到 c:\temp\uploadedfiles。我建议您Path.GetTempFileName()改用它,因为这可以保证为您提供一个无论您在什么环境下都可以随时写入的文件。

于 2011-10-12T18:08:39.573 回答
1

首先,如果您要像这样使用 ASP.NET ,则必须通过 Web 服务器上传。如果不在客户端浏览器上安装插件或使用 ActiveX 控件(或类似控件),您绝对不能直接从客户端机器上传到 FTP 服务器。

我假设您正在上传二进制文件;如果是这种情况,您使用StreamReaders 和StreamWriters 的方式可能会损坏文件的二进制内容。相反,我们可以使用该Stream.CopyTo方法将数据逐字从一个流移动到另一个流。

我已修改您的方法以改用此模式:

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

    Dim myFileStream As Stream = FileUpload1.FileContent
    myFtpWebRequest.ContentLength = myFileStream.Length

    Dim requestStream As Stream = myFtpWebRequest.GetRequestStream()
    myFileStream.CopyTo(requestStream)
    requestStream.Close()

    myFtpWebResponse = CType(myFtpWebRequest.GetResponse(), FtpWebResponse)
    myFtpWebResponse.Close()
End Sub
于 2011-10-13T22:52:41.050 回答
1

数据已损坏,因为您正在读取文件,就好像它是文本一样,但事实并非如此。

使用 aBinaryReader而不是 aStreamReader以便您可以直接将数据读取为字节:

Dim fileContents As Byte()
Using sourceStream As New BinaryReader(FileUpload1.FileContent)
  fileContents = sourceStream.ReadBytes(Int32.MaxValue)
End Using
于 2011-10-13T23:32:58.457 回答