0

In my vb application where i upload files to FTp website I use large size array. During declaring the array sometimes i get error like Exception of type 'System.OutOfMemoryException' was thrown.

I have declared array as

Const BufferSize As Integer = 400000000
Dim content(BufferSize - 1) As Byte

Actually 400000000 will come around 380 MB . I have got 4 GB RAM and usage is not high. Why does this error is shown sometimes? How it can be solved?

IT researcher
  • 3,274
  • 17
  • 79
  • 143

2 Answers2

0

Reffering to my earlier same question and answer (with thanks to Aik for his excellent explaination).

Even if you have 4gb ram there is no way to know that you have 380mb of continious space available. If you fragmentation of your RAM is too big this could result in problems.

You need to chuck your data to overcome this problem (see this answer...)

Explanation by AIK:

For Example on my machine I'm not able allocate more than 908 000 000 bytes in one array, but I can allocate 100 * 90 800 000 without any problem if it is stored in more arrays:

Dim toBigArray As Byte() = New Byte(908000000) {}
'doesn't work (6 zeroes after 908)
' allocation in more arrays
Dim a As Byte()() = New Byte(100)() {}

For i As Integer = 0 To a.Length - 1
    ' it works even there is 10x more memory needed than before
        ' (5 zeroes after 908) 
    a(0) = New Byte(90800000) {}
Next
Community
  • 1
  • 1
User999999
  • 2,500
  • 7
  • 37
  • 63
  • If i do as u said in the answer then how can i use this two dimension array in Filestrem . read function. It accepts single dimension array. – IT researcher Sep 17 '14 at 10:04
  • The point i was trying to make is that you can allocate too much memory into a single array. You'll end up getting yourself into troubles (eg. see your question). You must chunck it (like in the code example below). You can manually adjust your buffersize for optimal speed. – User999999 Sep 17 '14 at 10:10
0

Using such large arrays is a poor idea. You can stream the file in small chunks. Here is some sample code from this link

''' <summary>
''' Methods to upload file to FTP Server
''' </summary>
''' <param name="_FileName">local source file name</param>
''' <param name="_UploadPath">Upload FTP path including Host name</param>
''' <param name="_FTPUser">FTP login username</param>
''' <param name="_FTPPass">FTP login password</param>

Public Sub UploadFile(ByVal _FileName As String, ByVal _UploadPath As String, ByVal _FTPUser As String, ByVal _FTPPass As String)
Dim _FileInfo As New System.IO.FileInfo(_FileName)

' Create FtpWebRequest object from the Uri provided
Dim _FtpWebRequest As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(New Uri(_UploadPath)), System.Net.FtpWebRequest)

' Provide the WebPermission Credintials
_FtpWebRequest.Credentials = New System.Net.NetworkCredential(_FTPUser, _FTPPass)

' By default KeepAlive is true, where the control connection is not closed
' after a command is executed.
_FtpWebRequest.KeepAlive = False

' set timeout for 20 seconds
_FtpWebRequest.Timeout = 20000

' Specify the command to be executed.
_FtpWebRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile

' Specify the data transfer type.
_FtpWebRequest.UseBinary = True

' Notify the server about the size of the uploaded file
_FtpWebRequest.ContentLength = _FileInfo.Length

' The buffer size is set to 2kb
Dim buffLength As Integer = 2048
Dim buff(buffLength - 1) As Byte

' Opens a file stream (System.IO.FileStream) to read the file to be uploaded
Dim _FileStream As System.IO.FileStream = _FileInfo.OpenRead()

Try
' Stream to which the file to be upload is written
Dim _Stream As System.IO.Stream = _FtpWebRequest.GetRequestStream()

' Read from the file stream 2kb at a time
Dim contentLen As Integer = _FileStream.Read(buff, 0, buffLength)

' Till Stream content ends
Do While contentLen <> 0
' Write Content from the file stream to the FTP Upload Stream
_Stream.Write(buff, 0, contentLen)
contentLen = _FileStream.Read(buff, 0, buffLength)
Loop

' Close the file stream and the Request Stream
_Stream.Close()
_Stream.Dispose()
_FileStream.Close()
_FileStream.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message, "Upload Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub


HOW TO USE:  

 ' Upload file using FTP
   UploadFile("c:\UploadFile.doc", "ftp://FTPHostName/UploadPath/UploadFile.doc", "UserName", "Password")

EDIT 1:

Try these links may be it can help you.

1) My.Computer.Network.UploadFile

2) Improve Performance of FtpWebRequest

Community
  • 1
  • 1
prem
  • 3,348
  • 1
  • 25
  • 57
  • Before I was using 2048 as buffLength . But upload will be slow.I have tested it too. A 100 MB file takes 18 minutes to upload if i set 2048 as buffLength and it takes just 3 minutes if buffLength is 400000000 with same internet speed – IT researcher Sep 17 '14 at 06:48