使用 FTP FileUpload 上传的零大小文件

发布于 2024-12-09 06:12:03 字数 2869 浏览 0 评论 0原文

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

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

我确切地知道问题是什么,但我不知道如何解决它。我可以从 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:

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 :(

enter image description here

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

各自安好 2024-12-16 06:12:03

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

我假设您正在上传二进制文件;如果是这种情况,您使用 StreamReader 和 StreamWriter 的方式可能会损坏文件的二进制内容。相反,我们可以使用 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

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 StreamReaders and StreamWriters could be corrupting the binary contents of the file. Instead, we can use the Stream.CopyTo method to move the data verbatim from one stream to the other.

I've modified your method to use this pattern instead:

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
五里雾 2024-12-16 06:12:03

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 a WebRequest.

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.

醉态萌生 2024-12-16 06:12:03

数据会被损坏,因为您将文件当作文本来读取,但事实并非如此。

使用 BinaryReader 而不是 StreamReader,以便您可以直接以字节形式读取数据:

Dim fileContents As Byte()
Using sourceStream As New BinaryReader(FileUpload1.FileContent)
  fileContents = sourceStream.ReadBytes(Int32.MaxValue)
End Using

The data gets corrupted because you are reading the file as if it was text, but it's not.

Use a BinaryReader instead of a StreamReader so that you can read the data as bytes directly:

Dim fileContents As Byte()
Using sourceStream As New BinaryReader(FileUpload1.FileContent)
  fileContents = sourceStream.ReadBytes(Int32.MaxValue)
End Using
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文