1

使用以下函数将视频文件上传到我的 Web 服务器时,我收到以下异常。我正在使用此功能,因为我需要降低内存使用量,因为正在上传的视频文件超过 150MB。

引发的错误是:您必须在调用 [Begin]GetResponse 之前将 ContentLength 字节写入请求流。

我现在已经查看了几次代码,似乎根本没有注意到我哪里出错了,可能只需要第二双眼睛来发现我的错误!

功能:

Friend Function LowMemoryUploader(ByVal FilePath As String) As String
        ServicePointManager.ServerCertificateValidationCallback = (Function(sender, certificate, chain, sslPolicyErrors) True)
        Dim oUri As New Uri("http://mysite.com/upload.php")
        Dim NowTime As String = DateTime.Now.Ticks.ToString().Substring(0, 14)
        Dim strBoundary As String = "-----------------------------" & NowTime
        ' Set Filename
        Dim FileName As String = FilePath.Split(CChar("\")).Last()
        ' The trailing boundary string
        Dim boundaryBytes As Byte() = Encoding.ASCII.GetBytes(vbCr & vbLf & "--" & strBoundary & vbCr & vbLf)
        ' The post message header
        Dim sb As New StringBuilder()
        ' Add Variables
        sb.Append(strBoundary & vbCrLf & "Content-Disposition: form-data; name=""upload""" & vbCrLf & vbCrLf & "1" & vbCrLf)
        sb.Append(strBoundary & vbCrLf & "Content-Disposition: form-data; name=""upload_file""; filename=""" & FileName & """" & vbCrLf)
        sb.Append("Content-Type: video/" & FilePath.Split(".").Last())
        sb.Append(vbCrLf & vbCrLf)
        ' Set Header Bytes
        Dim strPostHeader As String = sb.ToString()
        Dim postHeaderBytes As Byte() = Encoding.UTF8.GetBytes(strPostHeader)
        ' The WebRequest
        Dim oWebrequest As HttpWebRequest = DirectCast(WebRequest.Create(oUri), HttpWebRequest)
        ' Set Request Settings
        System.Net.ServicePointManager.Expect100Continue = False
        oWebrequest.Method = "POST"
        oWebrequest.UserAgent = Useragent
        oWebrequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
        oWebrequest.ContentType = "multipart/form-data; boundary=---------------------------" & NowTime
        oWebrequest.AllowAutoRedirect = True
        oWebrequest.Timeout = 600000
        oWebrequest.CookieContainer = cookies
        ' This is important, otherwise the whole file will be read to memory anyway...
        oWebrequest.AllowWriteStreamBuffering = False
        ' Get a FileStream and set the final properties of the WebRequest
        Dim oFileStream As New FileStream(FilePath, FileMode.Open, FileAccess.Read)
        Dim length As Long = postHeaderBytes.Length + oFileStream.Length + boundaryBytes.Length
        oWebrequest.ContentLength = length
        Dim oRequestStream As Stream = oWebrequest.GetRequestStream()
        ' Write the post header
        oRequestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length)
        ' Stream the file contents in small pieces (4096 bytes, max).
        Dim buffer As Byte() = New Byte(1096) {}
        Dim bytesRead As Integer = oFileStream.Read(buffer, 0, buffer.Length)
        While bytesRead <> 0
            bytesRead = oFileStream.Read(buffer, 0, buffer.Length)
            oRequestStream.Write(buffer, 0, bytesRead)
        End While
        oFileStream.Close()
        ' Add the trailing boundary
        oRequestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
        Dim oWResponse As WebResponse = oWebrequest.GetResponse()
        Dim s As Stream = oWResponse.GetResponseStream()
        Dim sr As New StreamReader(s)
        Dim sReturnString As String = sr.ReadToEnd()
        ' Clean up
        oRequestStream.Close()
        s.Close()
        sr.Close()
        Return sReturnString
    End Function
4

1 回答 1

0

这部分看起来不正确:

Dim bytesRead As Integer = oFileStream.Read(buffer, 0, buffer.Length)
While bytesRead <> 0
    bytesRead = oFileStream.Read(buffer, 0, buffer.Length)
    oRequestStream.Write(buffer, 0, bytesRead)
End While

请注意,Dim bytesRead As Integer = oFileStream.Read(buffer, 0, buffer.Length)它会进行初始读取,但会在您的循环中立即被覆盖。因此,您向 中写入的块oRequestStream比您读取的要少。

于 2013-08-22T13:08:26.810 回答