HttpWebRequest FileUpload导致OutOfMemoryException [英] HttpWebRequest FileUpload causes OutOfMemoryException

查看:322
本文介绍了HttpWebRequest FileUpload导致OutOfMemoryException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我总是得到这个 OutOfMemoryException

  System.OutOfMemoryException was没有处理。 
Message =类型为System.OutOfMemoryException的异常被抛出。
Source = System
在System.Net.ScatterGatherBuffers.AllocateMemoryChunk(Int32 newSize)上的
$ System.Net.ScatterGatherBuffers.Write
(Byte [] buffer,Int32 offset, Int32 count)
at System.Net.ConnectStream.InternalWrite(Boolean async,Byte [] buffer,Int32 offset,Int32 size,AsyncCallback callback,Object state)
at System.Net.ConnectStream.Write(Byte []缓冲区,Int32偏移量,Int32大小)
...

...和内存使用情况(根据Windows任务管理器),当我执行下面的源代码:

  Imports System.Net 
Imports System.Text
Imports System.IO

Public Class HttpFileUploader
$ b Public Function uploadFile(ByVal containa As CookieContainer,ByVal uri As String,ByVal filePath As String, ByVal fileParameterName As String,ByVal contentType As String,ByVal otherParameters As Specialized.NameValueCollection)As String

Dim boundary As String =---------------------------& DateTime.Now.Ticks.ToString(x)
Dim newLine As String = System.Environment.NewLine
Dim boundaryBytes As Byte()= System.Text.Encoding.ASCII.GetBytes(newLine& - & boundary& newLine)
Dim请求As Net.HttpWebRequest = Net.WebRequest.Create(uri)

request.ContentType =multipart / form-data; boundary =&边界
request.Method =POST
request.CookieContainer = containa
request.AllowAutoRedirect = True
request.Timeout = -1

使用requestStream作为IO.Stream = request.GetRequestStream()

Dim formDataTemplate As String =Content-Disposition:form-data; name ={0}{1} {1} {2}

For Each Key As String in otherParameters.Keys

requestStream.Write(boundaryBytes,0,boundaryBytes.Length)
Dim formItem As String = String.Format (formDataTemplate,key,newLine,otherParameters(key))
Dim formItemBytes As Byte()= System.Text.Encoding.UTF8.GetBytes(formItem)
requestStream.Write(formItemBytes,0,formItemBytes.Length )

下一个键

requestStream.Write(boundaryBytes,0,boundaryBytes.Length)

Dim headerTemplate As String =Content-Disposi形式 - 数据;名称= {0} ;文件名={1}{2} Content-Type:{3} {2}
Dim header As String = String.Format(headerTemplate,fileParameterName,filePath,newLine,contentType)
Dim headerBytes As Byte()= System.Text.Encoding.UTF8.GetBytes(header)
requestStream.Write(headerBytes,0,headerBytes.Length)

使用fileStream As New IO.FileStream(filePath,IO.FileMode.Open,IO.FileAccess.Read)

Dim buffer(4096)As Byte
Dim bytesRead As Int32 = fileStream.Read(buffer,0,
$ b $ while(bytesRead> 0)
'异常由以下行触发:
requestStream.Write(buffer,0,bytesRead)
bytesRead = fileStream.Read(buffer,0,buffer.Length)
Loop

End使用

Dim trailer As Byte()= System.Text。 Encoding.ASCII.GetByte (newLine& - +边界+ - & newLine)
requestStream.Write(trailer,0,trailer.Length)
requestStream.Close()

结束使用

Dim net As Net。 WebResponse = Nothing
Dim responseText =

尝试

response = request.GetResponse()

使用responseStream作为IO.Stream = response.GetResponseStream()

使用responseReader作为新的IO.StreamReader(responseStream)

responseText = responseReader.ReadToEnd()

结束使用

End使用

捕获异常为Net.WebException

MsgBox(exception.Message)

最后

response.Close()
response = Nothing
request = Nothing

结束尝试

返回responseText

End Function

End Class

我用注释标记了触发异常的行。我使用10个线程上传不同的文件(大小高达250 MB)。

为什么我用这个代码耗尽内存?

解决方案

以下代码正在工作:

  System.Net 
Imports System.Text
Imports System.IO

公共类HttpFileUploader
$ b公共函数uploadFile(ByVal containa作为CookieContainer,ByVal uri As String,ByVal filePath As String,ByVal fileParameterName As String,ByVal contentType As String,ByVal otherParameters As Specialized.NameValueCollection)As String

Dim boundary As String =---------- -----------------& DateTime.Now.Ticks.ToString(x)
Dim newLine As String = System.Environment.NewLine
Dim boundaryBytes As Byte()= System.Text.Encoding.ASCII.GetBytes(newLine& - & boundary& newLine)
Dim请求As Net.HttpWebRequest = Net.WebRequest.Create(uri)

request.ContentType =multipart / form-data; boundary =& border
request.Method =POST
request.CookieContainer = containa
request.AllowAutoRedirect = True
request.Timeout = -1
request.KeepAlive = True
request.AllowWriteStreamBuffering = False

Dim ms As New MemoryStream()
Dim formDataTemplate As String =Content-Disposition:form-data; name ={0} {1} {1} {2}

对于每个键作为字符串在otherParameters.Keys
ms.Write(boundaryBytes,0,boundaryBytes.Length)
Dim formItem As String = String.Format(formDataTemplate,key,newLine,otherParameters(key))
Dim formItemBytes As Byte()= System.Text.Encoding.UTF8.GetBytes(formItem)
ms.Write(formItemBytes, 0,formItemBytes.Length)
下一个键

ms.Write(boundaryBytes,0,boundaryBytes.Length)

Dim headerTemplate As String =Content-Disposition: form-data; name ={0} ;文件名={1}{2} Content-Type:{3} {2}
Dim header As String = String.Format(headerTemplate,fileParameterName,filePath,newLine,contentType)
Dim headerBytes As Byte()= System.Text.Encoding.UTF8.GetBytes(header)
ms.Write(headerBytes,0,headerBytes.Length)

Dim length As Long = ms.Length
length + =新建FileInfo(filePath).Length
request.ContentLength = length

使用requestStream As IO.Stream = request.GetRequestStream()
)Dim bheader()As Byte = ms.ToArray()
requestStream.Write(bheader,0,bheader.Length)
使用fileStream作为新IO.FileStream(filePath,IO.FileMode.Open,IO .FileAccess.Read)

Dim buffer(4096)As Byte
Dim bytesRead As Int32 = fileStream.Read(buffer,0,buffer.Length)

while(bytesRead> 0)
requestStream.Write(buffer, 0,bytesRead)
bytesRead = fileStream.Read(buffer,0,buffer.Length)
Loop
End使用
requestStream.Close()
End使用

Dim response As Net.WebResponse = Nothing
Dim responseText =

Try

response = request.GetResponse()

使用responseStream As IO.Stream = response.GetResponseStream()

使用responseReader作为新IO.StreamReader(responseStream)

responseText = responseReader.ReadToEnd()

结束使用

结束使用

捕获异常为Net.WebException

MsgBox(exception.Message)

最后

response.Close()
响应=没有
请求=没有
结束尝试

返回responseT ext

End Function

End Class

很多很多,谢谢汤姆和那个来自 http://blogs.msdn.com/b/johan/archive/2006/11/15/are-you-getting-outofmemoryexceptions-when-uploading-large-files.aspx !!!

I always get this OutOfMemoryException:

 System.OutOfMemoryException was not handled.
 Message=Exception of type 'System.OutOfMemoryException' was thrown.
 Source=System
 StackTrace:
    at System.Net.ScatterGatherBuffers.AllocateMemoryChunk(Int32 newSize)
    at System.Net.ScatterGatherBuffers.Write(Byte[] buffer, Int32 offset, Int32 count)
    at System.Net.ConnectStream.InternalWrite(Boolean async, Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
    at System.Net.ConnectStream.Write(Byte[] buffer, Int32 offset, Int32 size)
    …

... and memory usage is steadily increasing (according to the Windows task manager) when I execute following source code:

Imports System.Net
Imports System.Text
Imports System.IO

Public Class HttpFileUploader

    Public Function uploadFile(ByVal containa As CookieContainer, ByVal uri As String, ByVal filePath As String, ByVal fileParameterName As String, ByVal contentType As String, ByVal otherParameters As Specialized.NameValueCollection) As String

        Dim boundary As String = "---------------------------" & DateTime.Now.Ticks.ToString("x")
        Dim newLine As String = System.Environment.NewLine
        Dim boundaryBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(newLine & "--" & boundary & newLine)
        Dim request As Net.HttpWebRequest = Net.WebRequest.Create(uri)

        request.ContentType = "multipart/form-data; boundary=" & boundary
        request.Method = "POST"
        request.CookieContainer = containa
        request.AllowAutoRedirect = True
        request.Timeout = -1

        Using requestStream As IO.Stream = request.GetRequestStream()

            Dim formDataTemplate As String = "Content-Disposition: form-data; name=""{0}""{1}{1}{2}"

            For Each key As String In otherParameters.Keys

                requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
                Dim formItem As String = String.Format(formDataTemplate, key, newLine, otherParameters(key))
                Dim formItemBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(formItem)
                requestStream.Write(formItemBytes, 0, formItemBytes.Length)

            Next key

            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)

            Dim headerTemplate As String = "Content-Disposition: form-data; name=""{0}""; filename=""{1}""{2}Content-Type: {3}{2}{2}"
            Dim header As String = String.Format(headerTemplate, fileParameterName, filePath, newLine, contentType)
            Dim headerBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(header)
            requestStream.Write(headerBytes, 0, headerBytes.Length)

            Using fileStream As New IO.FileStream(filePath, IO.FileMode.Open, IO.FileAccess.Read)

                Dim buffer(4096) As Byte
                Dim bytesRead As Int32 = fileStream.Read(buffer, 0, buffer.Length)

                Do While (bytesRead > 0)
                    ' the exception is triggered by the following line:     
                    requestStream.Write(buffer, 0, bytesRead)
                    bytesRead = fileStream.Read(buffer, 0, buffer.Length)
                Loop

            End Using

            Dim trailer As Byte() = System.Text.Encoding.ASCII.GetBytes(newLine & "--" + boundary + "--" & newLine)
            requestStream.Write(trailer, 0, trailer.Length)
            requestStream.Close()

        End Using

        Dim response As Net.WebResponse = Nothing
        Dim responseText = ""

        Try

            response = request.GetResponse()

            Using responseStream As IO.Stream = response.GetResponseStream()

                Using responseReader As New IO.StreamReader(responseStream)

                    responseText = responseReader.ReadToEnd()

                End Using

            End Using

        Catch exception As Net.WebException

            MsgBox(exception.Message)

        Finally

            response.Close()
            response = Nothing
            request = Nothing

        End Try

        Return responseText

    End Function

End Class

I have marked with a comment the line that triggers the exception.

I'm using 10 threads for uploading different files (having sizes up to 250 MB).

Why am I running out of memory with this code?

解决方案

Following code is working:

Imports System.Net
Imports System.Text
Imports System.IO

Public Class HttpFileUploader

    Public Function uploadFile(ByVal containa As CookieContainer, ByVal uri As String, ByVal filePath As String, ByVal fileParameterName As String, ByVal contentType As String, ByVal otherParameters As Specialized.NameValueCollection) As String

        Dim boundary As String = "---------------------------" & DateTime.Now.Ticks.ToString("x")
        Dim newLine As String = System.Environment.NewLine
        Dim boundaryBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(newLine & "--" & boundary & newLine)
        Dim request As Net.HttpWebRequest = Net.WebRequest.Create(uri)

        request.ContentType = "multipart/form-data; boundary=" & boundary
        request.Method = "POST"
        request.CookieContainer = containa
        request.AllowAutoRedirect = True
        request.Timeout = -1
        request.KeepAlive = True
        request.AllowWriteStreamBuffering = False

        Dim ms As New MemoryStream()
        Dim formDataTemplate As String = "Content-Disposition: form-data; name=""{0}""{1}{1}{2}"

        For Each key As String In otherParameters.Keys
            ms.Write(boundaryBytes, 0, boundaryBytes.Length)
            Dim formItem As String = String.Format(formDataTemplate, key, newLine, otherParameters(key))
            Dim formItemBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(formItem)
            ms.Write(formItemBytes, 0, formItemBytes.Length)
        Next key

        ms.Write(boundaryBytes, 0, boundaryBytes.Length)

        Dim headerTemplate As String = "Content-Disposition: form-data; name=""{0}""; filename=""{1}""{2}Content-Type: {3}{2}{2}"
        Dim header As String = String.Format(headerTemplate, fileParameterName, filePath, newLine, contentType)
        Dim headerBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(header)
        ms.Write(headerBytes, 0, headerBytes.Length)

        Dim length As Long = ms.Length
        length += New FileInfo(filePath).Length
        request.ContentLength = length

        Using requestStream As IO.Stream = request.GetRequestStream()
            Dim bheader() As Byte = ms.ToArray()
            requestStream.Write(bheader, 0, bheader.Length)
            Using fileStream As New IO.FileStream(filePath, IO.FileMode.Open, IO.FileAccess.Read)

                Dim buffer(4096) As Byte
                Dim bytesRead As Int32 = fileStream.Read(buffer, 0, buffer.Length)

                Do While (bytesRead > 0)
                    requestStream.Write(buffer, 0, bytesRead)
                    bytesRead = fileStream.Read(buffer, 0, buffer.Length)
                Loop
            End Using
            requestStream.Close()
        End Using

        Dim response As Net.WebResponse = Nothing
        Dim responseText = ""

        Try

            response = request.GetResponse()

            Using responseStream As IO.Stream = response.GetResponseStream()

                Using responseReader As New IO.StreamReader(responseStream)

                    responseText = responseReader.ReadToEnd()

                End Using

            End Using

        Catch exception As Net.WebException

            MsgBox(exception.Message)

        Finally

            response.Close()
            response = Nothing
            request = Nothing
        End Try

        Return responseText

    End Function

End Class

Many many thanks to Tom and the guy from http://blogs.msdn.com/b/johan/archive/2006/11/15/are-you-getting-outofmemoryexceptions-when-uploading-large-files.aspx!!!

这篇关于HttpWebRequest FileUpload导致OutOfMemoryException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆