|
-
Jul 16th, 2002, 07:30 PM
#1
Thread Starter
yay gay
how do i make syncronous downloads?
i searched for code to download files with vb.net...i came out with this:
string remoteUri = "http://www.contoso.com/library/homepage/images/";
string fileName = "ms-banner.gif", myStringWebResource = null;
// Create a new WebClient instance.
WebClient myWebClient = new WebClient();
// Concatenate the domain with the Web resource filename.
myStringWebResource = remoteUri + fileName;
listBox1.Items.Add("Downloading File "+fileName.ToString()+" from "+myStringWebResource.ToString()+" ....");
// Download the Web resource and save it into the current filesystem folder.
myWebClient.DownloadFile(myStringWebResource,fileName);
listBox1.Items.Add("Successfully Downloaded File "+fileName.ToString() +" from "+myStringWebResource.ToString());
listBox1.Items.Add("Downloaded file saved in the following file system folder:");
listBox1.Items.Add(Application.StartupPath.ToString() );
it's in C#, but no problem, i can turn it into VB easyly...the problem is that the program freezes while downloading...how do i download files without the all program freezes while downloading...?
-
Jul 16th, 2002, 08:23 PM
#2
Look up multithreading in the MSDN Library...
Awe, what the hell, I got some time, here is the link...
http://www.msdn.microsoft.com/librar...ingExample.asp
-
Jul 17th, 2002, 01:53 AM
#3
I wrote a class for downloading a file in a seperate thread, but i have got the code at home, and I am at work right now.
I didn't use the DownloadFile method of the WebClient class, because I would like to monitor the progress made.
I will post it as soon as I get home (in about 8 hours).
-
Jul 17th, 2002, 11:11 AM
#4
OK, here we go.
The downloadworker class is designed to run in a seperate thread.
So create a new object of this class. Set some properties (if not provided while creating the object) and start a new thread at the DownloadFile method. The thread will die as soon as the download is complete or fails.
Be aware that the class is designed for one thread for one object, so if you want to download multiple files at the same time, you need to create multiple objects.
First the code for the class:
VB Code:
Option Explicit On
Option Strict On
Imports System
Imports System.Net
Imports System.Text
Public Class DownloadWorker
Private _size As Long
Private mRead As Long
Private _status As DownLoadStatus
Private _errorDescription As String
Private _sourceURL As String
Private _destPath As String
Private _referer As String
Public Sub New()
MyBase.new()
_status = DownLoadStatus.Idle
End Sub
Public Sub New(ByVal sSourceURL As String, ByVal sDestPath As String)
MyBase.new()
_sourceURL = sSourceURL
_destPath = sDestPath
End Sub
Public Sub New(ByVal sSourceURL As String, ByVal sDestPath As String, ByVal sReferer As String)
MyBase.new()
_sourceURL = sSourceURL
_destPath = sDestPath
_referer = sReferer
End Sub
Public Enum DownLoadStatus
Idle = 0
Connecting = 1
Connected = 2
Downloading = 3
Completed = 4
ErrorOccured = 5
End Enum
Public Event StatusChanged(ByRef sender As DownloadWorker, ByVal OldStatus As DownLoadStatus, ByVal NewStatus As DownLoadStatus)
Public Event ProgressChanged(ByRef sender As DownloadWorker)
Public Property SourceURL() As String
Get
Return _sourceURL
End Get
Set(ByVal Value As String)
Select Case _status
Case DownLoadStatus.Connected, DownLoadStatus.Connecting, DownLoadStatus.Downloading
Throw New InvalidOperationException("SourceURL cannot be changed while download is in progress")
Case Else
_sourceURL = Value
End Select
End Set
End Property
Public Property DestPath() As String
Get
Return _destPath
End Get
Set(ByVal Value As String)
Select Case _status
Case DownLoadStatus.Connected, DownLoadStatus.Connecting, DownLoadStatus.Downloading
Throw New InvalidOperationException("Destination Path cannot be changed while download is in progress")
Case Else
_destPath = Value
End Select
End Set
End Property
Public Property Referer() As String
Get
Return _referer
End Get
Set(ByVal Value As String)
Select Case _status
Case DownLoadStatus.Connected, DownLoadStatus.Connecting, DownLoadStatus.Downloading
Throw New InvalidOperationException("Referer cannot be changed while download is in progress")
Case Else
_referer = Value
End Select
End Set
End Property
Public ReadOnly Property Status() As DownLoadStatus
Get
Return _status
End Get
End Property
Public ReadOnly Property Progress() As Double
Get
If _size = 0 Then
Return 0
Else
Return mRead / _size
End If
End Get
End Property
Public ReadOnly Property Size() As Long
Get
Return _size
End Get
End Property
Public ReadOnly Property Downloaded() As Long
Get
Return mRead
End Get
End Property
Public ReadOnly Property ErrorDescription() As String
Get
Return _errorDescription
End Get
End Property
Private Sub ChangeStatus(ByVal NewStatus As DownLoadStatus)
Dim Temp As DownLoadStatus
Temp = _status
_status = NewStatus
RaiseEvent StatusChanged(Me, Temp, NewStatus)
End Sub
Public Sub DownloadFile()
Dim bBuffer() As Byte
Const BlockSize As Integer = 4096
Dim iRead As Integer
Dim iReadTotal As Integer
Dim iTotalSize As Integer
If _sourceURL = "" Then
Throw New InvalidOperationException("No Source URL specified")
Exit Sub
End If
If _destPath = "" Then
Throw New InvalidOperationException("No Destination Path specified")
Exit Sub
End If
Try
Call ChangeStatus(DownLoadStatus.Connecting)
Dim wr As HttpWebRequest = CType(WebRequest.Create(_sourceURL), HttpWebRequest)
If _referer <> "" Then
wr.Referer = _referer
End If
Dim resp As HttpWebResponse = CType(wr.GetResponse(), HttpWebResponse)
_size = resp.ContentLength
Call ChangeStatus(DownLoadStatus.Connected)
Dim sIn As IO.Stream = resp.GetResponseStream
Dim sOut As New IO.FileStream(_destPath, IO.FileMode.Create)
ReDim bBuffer(BlockSize - 1)
Call ChangeStatus(DownLoadStatus.Downloading)
iRead = sIn.Read(bBuffer, 0, BlockSize)
mRead = iRead
While iRead > 0
RaiseEvent ProgressChanged(Me)
sOut.Write(bBuffer, 0, iRead)
iRead = sIn.Read(bBuffer, 0, BlockSize)
mRead += iRead
End While
sIn.Close()
sOut.Close()
Call ChangeStatus(DownLoadStatus.Completed)
Catch ex As Exception
_errorDescription = ex.Message
Call ChangeStatus(DownLoadStatus.ErrorOccured)
End Try
End Sub
End Class
-
Jul 17th, 2002, 11:18 AM
#5
If I have more time, I will extend the error handling, and maybe add the possibility to resume broken downloads, but for now I think it's a good example for a download in a seperate thread.
You can use the class like this.
Add a button (Download), and a label (Label1) to a form.
I omitted the form designer generated code.
VB Code:
Private WithEvents dlw As DownloadWorker
Private Sub DownLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DownLoad.Click
dlw = New DownloadWorker("http://www.vbforums.com/images/toptitle-1.gif", "c:\temp\world.gif")
Dim t As New Threading.Thread(AddressOf dlw.DownloadFile)
t.Start()
End Sub
Private Sub dlw_ProgressChanged(ByRef sender As DownloadWorker) Handles dlw.ProgressChanged
Label1.Text = Format(sender.Progress, "0 %")
End Sub
Private Sub dlw_StatusChanged(ByRef sender As DownloadWorker, ByVal OldStatus As DownloadClient.DownloadWorker.DownLoadStatus, ByVal NewStatus As DownloadClient.DownloadWorker.DownLoadStatus) Handles dlw.StatusChanged
Select Case NewStatus
Case DownloadWorker.DownLoadStatus.Completed
Label1.Text = "Completed"
Case DownloadWorker.DownLoadStatus.Connected
Label1.Text = "Connected"
Case DownloadWorker.DownLoadStatus.Connecting
Label1.Text = "Connecting"
Case DownloadWorker.DownLoadStatus.Downloading
Label1.Text = "Downloading"
Case DownloadWorker.DownLoadStatus.ErrorOccured
Label1.Text = sender.ErrorDescription
Case DownloadWorker.DownLoadStatus.Idle
Label1.Text = "Idle"
End Select
End Sub
-
Jul 17th, 2002, 12:49 PM
#6
Thread Starter
yay gay
-
Jul 29th, 2002, 05:05 AM
#7
Member
Very nice Class.. but this one is work for HTTP download only right? do you have some idea on how to download file from FTP as well?
-
Sep 6th, 2002, 08:51 AM
#8
Thread Starter
yay gay
the size function doesnt return the size...as well as progress doesnt report the progress...the only function that still works is the downloaded() but it sometimes return the value in negative number...but thats not problem...
-
Sep 6th, 2002, 09:25 AM
#9
I have noticed this as well when downloading from servers that don't return information about contentlength.
If the size is unknown, the progress is unknown as well.
Like I said, the error handling needs some work.
-
Sep 6th, 2002, 08:18 PM
#10
Thread Starter
yay gay
yea..that was the problem..he cannot save php and asp webpages :\
-
Sep 6th, 2002, 08:19 PM
#11
Thread Starter
yay gay
does anyone knows a way of workin around?
-
Sep 17th, 2002, 10:56 AM
#12
Thread Starter
yay gay
-
Sep 17th, 2002, 11:38 PM
#13
Thread Starter
yay gay
i noticed that when using this code the connection after the download is done never is closed...hmm..err
-
May 3rd, 2003, 10:32 PM
#14
Hyperactive Member
sweet! i like it a lot!
just one additional question though (sorry )
is there a way that you can view the web files properties too? by that i mean that i want to say to the user of my program "there is a new file for download that was created on the ..." and then give them the option to download it.
in the code below i give them the details of a file they're about to overwrite. does anybody know of a way to view these properties for a file sitting on a web server?
Code:
Private Function DisplayFileDetails_Local()
Dim fso As New FileSystemObject()
Try
txtLocalSize.Text = Format(fso.GetFile(txtFileName.Text).Size, "###,###,##0") & " bytes"
txtLocalLastModified.Text = Format(fso.GetFile(txtFileName.Text).DateLastModified, "dd MMM yyyy")
txtLocalLastAccessed.Text = Format(fso.GetFile(txtFileName.Text).DateLastAccessed, "dd MMM yyyy")
Catch
Debug.WriteLine(Err.Description)
End Try
End Function
thanks.
"The passion lives to keep your faith, though all are different, all are great" ... Michael Hutchence 1960-1997.
Windows & Web Developer
Specialising in Visual Basic .Net & Client Server Programming & Client/Customer Relations Databases
Sutherland Shire, Sydney Australia
www.stingrae.com.au
Developer of Arnold - Gym & Martial Arts Database Management System
www.gymdatabase.com.au
-
May 4th, 2003, 01:59 AM
#15
If you wanted to use the Webclient still you can easily make it run asynchronously with a new thread or via a delegate and the begininvoke method. Although that doesn't provide a method of showing the progress. I think to get the progress you'd have to use OpenRead on the webclient to get the stream of the file. Then you can grab it in chunks and show progress that way.
VB Code:
Public Delegate Sub DoDownloadFile(ByVal url As String, ByVal file As String)
Private Sub btnAsync_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAsync.Click
Dim wc As New WebClient()
'make delegate from object method
Dim del As New DoDownloadFile(AddressOf wc.DownloadFile)
'start the download
del.BeginInvoke(txtURL.Text, txtLocal.Text, New AsyncCallback(AddressOf DownloadProgress), Nothing)
'if you don't care to check the completion or not then you can use to run it async still
'del.BeginInvoke(txtURL.Text, txtLocal.Text, Nothing, Nothing)
End Sub
Private Sub DownloadProgress(ByVal ar As IAsyncResult)
'catch callbacks
If ar.IsCompleted Then
MsgBox("File Downloaded!")
Else
MsgBox("Download Failed!")
End If
End Sub
-
May 5th, 2003, 05:45 PM
#16
Sleep mode
Originally posted by Frans C
I have noticed this as well when downloading from servers that don't return information about contentlength.
If the size is unknown, the progress is unknown as well.
Like I said, the error handling needs some work.
It's not any sort of problems ! even Windows default downloader (and sometimes Downloader Manager) returns no size nor the estimated time (it just shows ..#.downloaded so far . Your Class seems well-done and thanks for sharing it with us Frans C .
-
May 6th, 2003, 12:45 AM
#17
Hyperactive Member
DownloadWorker is working fantastically! A big thanks to all of you on here.
Don't suppose anyone has an UploadWorker too do they? That would be a big help!
Last edited by stingrae; Jun 16th, 2003 at 12:35 AM.
"The passion lives to keep your faith, though all are different, all are great" ... Michael Hutchence 1960-1997.
Windows & Web Developer
Specialising in Visual Basic .Net & Client Server Programming & Client/Customer Relations Databases
Sutherland Shire, Sydney Australia
www.stingrae.com.au
Developer of Arnold - Gym & Martial Arts Database Management System
www.gymdatabase.com.au
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|