1

ドキュメントを Html Agility パックで保存した後、(FtpWebRequest を介して) ドキュメントをアップロードする際に問題が発生しました。HTML ファイルを編集して stringWriter に保存し、サーバーにアップロードしようとしています。こんな風に書類を保存しているのですが……

doc.OptionAutoCloseOnEnd = True
doc.OptionWriteEmptyNodes = True
Dim sr As New StringWriter
doc.Save(sr)

そして、msdn のものと同様に asyncFtpUpload サブを使用してアップロードしますが、いくつかの変更のみを行います (ファイル名の代わりに文字列を使用します)。

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
4

0 に答える 0