3

I have been working on a web browser in visual basic..Now,what I want to do is to the get file size before download it and when I click download I want to to get the number of the alrady downloaded Mbs(watch the picture)

..

Thank's for help!

Technologuy
  • 131
  • 3
  • 16
  • 1
    See [this](http://stackoverflow.com/a/17316323/3970387). But apparently, this method is slow because it maybe downloads the whole file to get its size... – Drarig29 Aug 28 '15 at 11:28
  • Got you a new, clean code for retrieving the file size of a download _without requiring it to get downloaded first!_ :) – Visual Vincent Sep 01 '15 at 20:25

3 Answers3

7

I've done some research, and this would probably be the most simple and "cleanest" way of getting a download's size (in bytes):

Public Function GetDownloadSize(ByVal URL As String) As Long
    Dim r As Net.WebRequest = Net.WebRequest.Create(URL)
    r.Method = Net.WebRequestMethods.Http.Head
    Using rsp = r.GetResponse()
        Return rsp.ContentLength
    End Using
End Function

Credit to Reed Kimble, who told me to dispose the WebResponse in my initial MSDN question.


The above code will read the response headers of the file, rather than reading the body of it. This means that the file does not require to get downloaded, just to check it's size.

This is the reason to why some codes requires the file to actually get downloaded at first; they're reading the file's body rather than it's headers.


Hope this helps!

Visual Vincent
  • 18,045
  • 5
  • 28
  • 75
6

Use the WebClient ResponseHeaders:

Public Shared Function GetFileSize(url As String) As Long
    Using obj As New WebClient()
        Using s As Stream = obj.OpenRead(url)
            Return Long.Parse(obj.ResponseHeaders("Content-Length").ToString())
        End Using
    End Using
End Function

Request file size before download it

Community
  • 1
  • 1
Minzkraut
  • 2,149
  • 25
  • 31
  • 1
    The problem with this, is that the whole file is downloaded to get its size. So it's slow. Let's see if the OP will like it. – Drarig29 Aug 28 '15 at 11:33
  • 1
    As #Drarig29 said, the whole file is downloaded to get its size..so,I can't get the number of the already downloaded Mbs while the file is being downloaded.. but thank's for your answer.. – Technologuy Aug 28 '15 at 11:50
  • 1
    And.. is it sure that it downloads the whole file before it gets it size? – Technologuy Aug 28 '15 at 12:12
  • @TechTechnology From all I've read, nobody's really sure about that, you should try. (By the way, use "@" and not "#" to quote someone) – Drarig29 Aug 28 '15 at 15:06
4

The WebClient's DownloadProgressChanged event's args contains the property TotalBytesToRecieve. That tells you how many bytes the file you're downloading is.

Not the prettiest way, but if you want to get the size of the file before downloading you can start downloading the file then immediately cancel it:

Dim DownloadSize As Long
Private Sub CheckDownloadSize(ByVal URL As String)
    WebClient.DownloadFile(URL, IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Temp, "tempdownload.tmp"))
End Sub

Private WithEvents WebClient As New WebClient
Private Sub WebClient_DownloadProgressChanged(ByVal sender As Object, ByVal e As System.Net.DownloadProgressChangedEventArgs) Handles WebClient.DownloadProgressChanged
    DownloadSize = e.TotalBytesToReceive
    WebClient.CancelAsync()
End Sub

Otherwise, just remove the .CancelAsync() line.

Visual Vincent
  • 18,045
  • 5
  • 28
  • 75
  • 2
    @TechTechnology : And this doesn't download the whole file, but perhaps a few KB of it. – Visual Vincent Aug 29 '15 at 23:25
  • @sunilkarkala : Glad to hear that! However if you use this _only_ to get the download size but not actually download it yet, I recommend my other answer. But the choice is yours. :) – Visual Vincent Mar 11 '17 at 08:35
  • i tried the above code , but the event progress changed event called four to five time , even after calling WebClient.CancelAsync() , can u tell me why it happens like that, is webclient takes time to close that async calling. – sunilkarkala Mar 11 '17 at 08:51
  • @sunilkarkala : Don't know, but you could remove the event handler from itself. Put this after CancelAsync: `RemoveHandler WebClient.DownloadProgressChanged, AddressOf WebClient_DownloadProgressChanged` – Visual Vincent Mar 11 '17 at 08:54
  • @sunilkarkala : Still though, my other answer (the accepted one) is the very best way to go, so I don't see why you would want to use this one instead. ;) – Visual Vincent Mar 11 '17 at 08:55
  • actually i was working with web client , so i thought to continue with that , if u suggest that is the best way to do , then i will try that , thank you. – sunilkarkala Mar 11 '17 at 09:00
  • @sunilkarkala : You can still use the `WebClient` _to actually download the file_, but for only getting the download size this answer is more of a hacky workaround while my other one is the correct way to do it. – Visual Vincent Mar 11 '17 at 09:02
  • i was working on downloading bigger files from remote location , i was trying to do it by segmented download, but to segment the download first i have to get the actual file size, i tried to download using webclient , but if the file size is big , some times it will file , this is the problem i am facing , do u know any other method other than segmented download. – sunilkarkala Mar 11 '17 at 09:09
  • @sunilkarkala : I don't know any other method, no. But [**here's a question**](http://stackoverflow.com/questions/25789921/downloading-a-file-in-multiple-chunks) about downloading a file in segments, perhaps the code can be of help. – Visual Vincent Mar 11 '17 at 09:15