在使用 Html Agility 包保存文档后,我一直在努力解决文档上传(通过 FtpWebRequest)的一些问题。我正在尝试编辑一个 html 文件,然后将其保存到 stringWriter,然后将其上传到服务器。我正在像这样保存文档...
doc.OptionAutoCloseOnEnd = True
doc.OptionWriteEmptyNodes = True
Dim sr As New StringWriter
doc.Save(sr)
然后使用 asyncFtpUpload sub 上传它,就像 msdn 上的那样,但只有一些更改(而不是文件名,我使用字符串)
http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx#Y3024
这样做的结果是上传的文件被截断了最后一个字节。当我在服务器上看到该文件的源代码时,它错过了 <\html> 标记。我已经调试了代码并且在 doc.save() 上创建的字符串是正确的,然后在上传例程中,当我使用 getBytes() 时它仍然是正确的,并且 requestStream 写入方法写入了正确的流长度。我无法弄清楚这段代码发生了什么。
谁能帮我解决这个问题?
这是代码:
Dim outStream As MemoryStream = New MemoryStream(ASCIIEncoding.Default.GetBytes(str))
Dim uploader As AsynchronousFtpUpLoader = New AsynchronousFtpUpLoader
uploader.startUpload(pag, outStream)
和班级:
公共类 AsynchronousFtpUpLoader
Public Sub startUpload(ByVal pag As FtpPage, ByVal stream As Stream)
Try
Dim waitObject As ManualResetEvent
Dim target As New Uri(pag.currentUrl)
Dim state As New FtpState()
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(target), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.UploadFile
request.UseBinary = False
request.Credentials = New NetworkCredential(pag.login, pag.password)
state.Request = request
state.stream = stream
' Get the event to wait on.
waitObject = state.OperationComplete
' Asynchronously get the stream for the file contents.
request.BeginGetRequestStream(New AsyncCallback(AddressOf EndGetStreamCallback), state)
' Block the current thread until all operations are complete.
waitObject.WaitOne()
' The operations either completed or threw an exception.
If state.OperationException IsNot Nothing Then
Throw state.OperationException
Else
End If
Catch ex As Exception
End Try
End Sub
Private Shared Sub EndGetStreamCallback(ByVal ar As IAsyncResult)
Dim state As FtpState = DirectCast(ar.AsyncState, FtpState)
Dim requestStream As Stream = Nothing
Try
requestStream = state.Request.EndGetRequestStream(ar)
Const bufferLength As Integer = 2048
Dim buffer As Byte() = New Byte(bufferLength) {}
Dim readBytes As Integer = 0
Dim stream As MemoryStream = state.stream
Do
readBytes = stream.Read(buffer, 0, bufferLength)
If readBytes <> 0 Then
requestStream.Write(buffer, 0, readBytes)
End If
Loop While readBytes <> 0
requestStream.Flush()
state.stream.Close()
requestStream.Close()
state.Request.BeginGetResponse(New AsyncCallback(AddressOf EndGetResponseCallback), state)
Catch e As Exception
state.OperationException = e
state.OperationComplete.[Set]()
Return
End Try
End Sub
Private Shared Sub EndGetResponseCallback(ByVal ar As IAsyncResult)
Dim state As FtpState = DirectCast(ar.AsyncState, FtpState)
Dim response As FtpWebResponse = Nothing
Try
response = DirectCast(state.Request.EndGetResponse(ar), FtpWebResponse)
response.Close()
state.StatusDescription = response.StatusDescription
state.OperationComplete.[Set]()
Catch e As Exception
state.OperationException = e
state.OperationComplete.[Set]()
End Try
End Sub