【问题标题】:Zero size files uploaded with FTP FileUpload使用 FTP FileUpload 上传的零大小文件
【发布时间】:2011-12-06 08:44:48
【问题描述】:

我最近一直在阅读大量关于 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

非常感谢 Adam Maras 的精彩回答。我会把我的错误留在这里,让其他找到这个帖子的人受益;)

【问题讨论】:

  • @Jim:那么当服务器无法访问客户端文件路径时,我该怎么做呢? FileUpload 控件至少不支持这个。
  • 您是否尝试先从文件上传中保存文件,然后尝试将其发送到 ftp 服务器?
  • @atbebtg 不,因为您应该能够将其直接发送到 FTP。通过网络服务器似乎很荒谬。如果这是唯一的方法,我不知道。我只是想逐个解决这个问题,但这让我发疯。

标签: asp.net vb.net ftp client ftp-server


【解决方案1】:

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

使用BinaryReader 而不是StreamReader,这样您就可以直接将数据读取为字节:

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

【讨论】:

  • 在上面的代码中你在哪里使用 BinaryReader?我只看到 StreamReader 。你能详细说明一下吗?
  • @Eyalk:我更正了代码,感谢您发现它。它一直应该是代码中的BinaryReader,因为它使用的是ReadBytes 方法。 StreamReader 类中没有这样的方法。
【解决方案2】:

首先,如果您要像这样使用 ASP.NET,您必须通过网络服务器上传。如果不在客户端浏览器上安装插件或使用 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

【讨论】:

  • 天哪!!有效!!我不得不对其进行一些修改,因为您是用 C# 风格编写的,但使用的是 VB,哈哈。说真的,我的大脑完全炸了。我永远感激不尽。非常非常非常感谢!! :)
【解决方案3】:

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(),因为这样可以保证给你一个无论你在什么环境下都可以随时写入的文件。

【讨论】:

  • 确实如此。正如您在我的代码中看到的那样,我的一次尝试写入了 FTP 服务器,但实际上并没有写入数据。我已经查看了您之前链接的两个页面。我无法使用 WebRequest 文章使代码工作,但我会再看一下。如果你这么好心,我仍然会很感激一些代码(或编辑我的)。谢谢:)
  • 据我所知,您的尝试 #3 实际上并未在本地写入文件。添加File1.SaveAs( // temp. file // ),您就可以开始了。
  • 我尝试了你的建议,但我上传的文件中仍然没有数据:(请在我的帖子中查看我的更新和截图。非常感谢你的帮助:)
猜你喜欢
  • 1970-01-01
  • 2020-01-29
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
  • 1970-01-01
  • 2016-02-07
  • 1970-01-01
  • 2015-07-09
相关资源
最近更新 更多