Search code examples
vb.netftpprogress-barbackgroundworker

How to get the file's size using FtpWebResponse


Trying to download file from a FTP to get download progress i have planned to implement backgroundWorker,the following code will display the download progress,speed,amount of kb downloading in the UI Following is the code i wrote in backgroundWorker_doWork

 'Creating the request and getting the response
    Dim theResponse As FtpWebResponse
    Dim theRequest As FtpWebRequest
    Try 
        'Checks if the file exist
        theRequest = WebRequest.Create(Me.txtFileName.Text)
        theResponse = theRequest.GetResponse
    Catch ex As Exception
        MessageBox.Show("An error occurred while downloading file. Possible causes:" & ControlChars.CrLf & _
                        "1) File doesn't exist" & ControlChars.CrLf & _
                        "2) Remote server error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

        Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
        Me.Invoke(cancelDelegate, True)
        Exit Sub
    End Try

    Dim length As Long = theResponse.ContentLength 'Size of the response (in bytes)
    Dim safedelegate As New ChangeTextsSafe(AddressOf ChangeTexts)
    Me.Invoke(safedelegate, length, 0, 0, 0) 'Invoke the TreadsafeDelegate
    Dim writeStream As New IO.FileStream(Me.whereToSave, IO.FileMode.Create)
    'Replacement for Stream.Position (webResponse stream doesn't support seek)
    Dim nRead As Integer
    'To calculate the download speed
    Dim speedtimer As New Stopwatch
    Dim currentspeed As Double = -1
    Dim readings As Integer = 0

    Do
        If BackgroundWorker1.CancellationPending Then 'If user abort download
            Exit Do
        End If
        speedtimer.Start()
        Dim readBytes(4095) As Byte
        Dim bytesread As Integer = theResponse.GetResponseStream.Read(readBytes, 0, 4096)
        nRead += bytesread
        Dim percent As Short = (nRead * 100) / length
        Me.Invoke(safedelegate, length, nRead, percent, currentspeed)
        If bytesread = 0 Then Exit Do
        writeStream.Write(readBytes, 0, bytesread)
        speedtimer.Stop()
        readings += 1
        If readings >= 5 Then 'For increase precision, the speed it's calculated only every five cicles
            currentspeed = 20480 / (speedtimer.ElapsedMilliseconds / 1000)
            speedtimer.Reset()
            readings = 0
        End If
    Loop

    'Close the streams
    theResponse.GetResponseStream.Close()
    writeStream.Close()

    If Me.BackgroundWorker1.CancellationPending Then
        IO.File.Delete(Me.whereToSave)
        Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
        Me.Invoke(cancelDelegate, True)
        Exit Sub
    End If

    Dim completeDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
    Me.Invoke(completeDelegate, False)
  • following is the error i got enter image description here
  • Dim length As Long = theResponse.ContentLength getting -1
  • For example

ftp://username:[email protected]/masters/5/party/party.csv

  • above given is the ftp Url am passing to download file, here party.csv is the file to download NOTE : the problem is when getting the file size of the file to download in my case the size of party,csv, Dim length As Long = theResponse.ContentLength. here theResponse.ContentLength getting -1 the actual size of the file is 420KB if i change Dim length As Long =430080(420kb=430080bytes) the code will work

Solution

  • Found the following solution to get the exact method to find the file's size

        Dim request As FtpWebRequest = DirectCast(WebRequest.Create(Me.txtFileName.Text), FtpWebRequest)
        request.Method = WebRequestMethods.Ftp.GetFileSize
        Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
        Dim fileSize As Long = response.ContentLength