Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Inet Control Performance problem 3

Status
Not open for further replies.

skiflyer

Programmer
Sep 24, 2002
2,213
US
I use an INet control to download a few files... and any files over 10 or so megs are just unbearably slow. I have other programs which download the same files usings BITS technology, and also a similar program using the WebClient in .NET and in both those cases the downloads run just fine... so I'm able to eliminate network issues and the like... and basically narrow it down to this INet Control.

Is there a better way for me to download large files from within a VB 6.0 Program, or even just another option I could play with?

Below is how I'm using INet control to download the files...

Code:
Private Sub GetFile(sSource As String, sDestination As String)
    Debug.Print sSource, sDestination
    Dim x() As Byte
    Inet1.URL = sSource
    x = Inet1.OpenURL(, icByteArray)
    Open sDestination For Binary Access Write As #1
    Put #1, , x()
    Close #1
End Sub

Thanks for any and all help.

-Rob
 
wow that was fast, but all the files are 0 bytes!

I'm definately thinking this is the way to go though, any tweaks I need on the server or in my program so the files have some meat to them though?

-Rob
 
By the way, I'm guessing what's happening is I'm getting the first 1k, then stopping... so I need to loop somehow, but that doesn't quite make sense given what's happening, and if it does, how do I stop when finished?

I'm confused.

-Rob
 
Okay.

What you want todo is the following.

data = Inet1.GetChunk(1024, icByteArray)

DoWhile LenB(data) > 0
Put #1,,data

'get a chunk
data = Inet1.GetChunk(1024, icByteArray)
Loop

Put #1,, data
Close #1

Try that, I wrote it right into the screen so there may be some syntax mistakes.

Let me know

I can't recall if it only works with ftp or http. Also take a look at Inet1.Execute, as well as to indicate a request at that point.
 
So I modified it slightly, because that Do While wouldn't evaluate... this gives me an infinite loop.

Data = Inet1.GetChunk(1024, icByteArray)
Open sDestination For Binary Access Write As #1

Do While (LenB(Data(0)) > 0)
Put #1, , Data
'get a chunk
Data = Inet1.GetChunk(1024, icByteArray)
Debug.Print "In loop" & LenB(Data(0))
Loop

Put #1, , Data()
Close #1


That puts me in an endless loop though, while the file on the harddrive stays at size 0.

Thanks for helping me with this.

-Rob
 
put that in in the Inet1_StateChanged(ByVal State as Integer)

then have another method do this:

Private Sub cmdGetFile_Click()
Dim command as String

Inet1.Url = "Site_Name"
Inet1.Username "uname"
Inet1.password "pword"

command = "get " & fileNameOnServer & fileSaveName

Call Inet1.Execute(, command)
end sub

now that will automatically fire the event StateChanged.

Try that. but this is for ftp, I wasn't sure which you needed ftp or http. Let me know

 
I need it for HTTP actually... mucking aroudn with some other details, but will get back to this shortly.
 
Here we go. found some code. You of course need to modify the form controls to your liking. Enjoy. And let me know.


Private Sub Command1_Click()
' Init the progressbar
ProgressBar1.Value = 0
' Set the status label to ""
Label1.Caption = ""
' The Execute method takes four optional parameters,
' of which we will use two, url and operation.
' The url parameter is a string value with any valid
' url and the operation can be GET, HEAD, POST, PUT.
' We will use GET in this example, which gives us the
' data of the specified url. Information about the
' others can be found if you follow one of the
' specified external links in the end of the article.
Inet1.Execute Text1.Text, "GET"
End Sub

' --------------------------------------------------------
' Private Sub Inet1_StateChanged
' Sub handles the stateChanged event
' Parameters: State As Integer
' Return Value: n/a
Private Sub Inet1_StateChanged(ByVal State As Integer)
' State 12 means that there is data in the buffer to collect
If State = 12 Then
Dim bolDone As Boolean: bolDone = False
Dim varData As Variant ' Data variable
Dim byteTempArray() As Byte
Dim intFile As Integer ' FreeFile variable
Dim lngFileSize As Long ' Filesize of remote file
Dim dblIncrease As Double ' Increase value for progress bar

intFile = FreeFile() ' Set intFile to an unused file.

' Get the file size
lngFileSize = Inet1.GetHeader("Content-length")
' Determine the increase value
dblIncrease = FormatNumber((1024 / lngFileSize) * 100, 4)
' Open a file for binary access
Open Text2.Text & "\" & GetFileName(Text1.Text) For Binary Access Write As #intFile
' Get the first chunk of data
varData = Inet1.GetChunk(1024, icByteArray)
DoEvents

Do While Not bolDone
byteTempArray = varData
' Write the content of the byte array to the opened file.
Put #intFile, , byteTempArray

If Not ProgressBar1.Value >= 100 Then
If Not ProgressBar1.Value + dblIncrease > 100 Then
ProgressBar1.Value = ProgressBar1.Value + dblIncrease
Else
ProgressBar1.Value = 100
End If
End If

' Get next chunk of data
varData = Inet1.GetChunk(1024, icByteArray)
DoEvents

' If we are not receiving any more, stop looping
If Len(varData) = 0 Then
bolDone = True
End If
Loop
' Close the file
Close #intFile
End If
' Print out the state to a label
Label1.Caption = GetCurrentState(State)
End Sub

' --------------------------------------------------------
' Private function GetCurrentState
' Function describes a certain state with words
' Parameters: intState As Integer
' Return Value: State description As string
Private Function GetCurrentState(intState As Integer) As String
Select Case intState
Case 0 ' icNone
GetCurrentState = "No state to report"
Case 1 ' icHostResolvingHost
GetCurrentState = "The control is looking up hte IP address of the specified host computer"
Case 2 ' icHostResolved
GetCurrentState = "The control successfully found the IP address of the specified host computer"
Case 3 ' icConnecting
GetCurrentState = "The control is connectiong to the host computer"
Case 4 ' icConnected
GetCurrentState = "The control successfully connected to the host computer"
Case 5 ' icRequesting
GetCurrentState = "The control is sending a request to the host computer"
Case 6 ' icRequestSent
GetCurrentState = "The control successfully sent the request"
Case 7 ' icReceivingResponse
GetCurrentState = "The control is receiving a response from the host computer"
Case 8 ' icResponseReceived
GetCurrentState = "The control successfully received a response from the host computer"
Case 9 ' icDisconnecting
GetCurrentState = "The control is disconnection from the host computer"
Case 10 ' icDisconnected
GetCurrentState = "The control successfully disconnected from the host computer"
Case 11 ' icError
GetCurrentState = "An error occured in communicating with the host computer"
Case 12 ' icResponseCompleted
GetCurrentState = "The request has completed and all data has been received"
Case Else
GetCurrentState = "Unknown state: " & intState
End Select
End Function

' --------------------------------------------------------
' Private function GetFileName
' Function resolves the filename from a full url
' Parameters: strUrl As string
' Return Value: filename As string
Private Function GetFileName(strUrl As String) As String
GetFileName = Mid(strUrl, InStrRev(strUrl, "/") + 1)
End Function
 
That's a beaut... thanks so much, I have it running in a test application, now I just need to modify it and port it over to the real thing.

Just for the sake of appeasing my users while they download large files... could you point me to that status bar control, be it a download, or something I can include as a reference?

I don't have it on my list of controls.

And again, thank you!

-Rob
 
The standard ProgressBar control is in Microsoft Common Controls 6 (MSCOMCTL.OCX)
________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first

'People who live in windowed environments shouldn't cast pointers.'
 
Are you talking about the progress bar (there is no Status Bar). Easy enough open components and locate Microsoft Windows Common Controls 6 (SP6) or locate the following file: MSCOMCTL.OCX it should be in system32.
 
You guys are too good to me! Now to integrate...

-Rob
 
Ok, so as a stand alone app that worked great, click and only click when the thing finishes the download... I'm now including it in my program which does uses a foreach loop to download several files.

Originally I put it all in a separate form and set the variables there, then called a function which did the same thing as command1.click

But that didn't work, so I migrated everything to my main form since it wasn't doing anything anyway, and activate it the same way... also doesn't work.

The problem I'm having is my program just flies through and doesn't wait for the download to finish.

If I try multiple files this results in an error from Inet Control that I didn't wait for the previous function to finish executing... if I do 1 file, my program finishes and exits before the download is done.

Any advice?

Thanks again,
Rob
 
In case I wasn't clear, what I need is a way for this subroutine to really grab control and halt the execution of the rest of my script until it's finished.

-Rob
 
So here's the logic of my workaround... I'll implement it tomorrow unless someone shares with me a better way first.

So, all of this right now is on a second form, activated by a function called download. (Form2.download())

So I'll store my location in my array of files with a state variable in form 1, then I'll call Form2.download

I'll have Form2 call a function in form1 which advances through the array, re-calling form2.

and so on, until my array is empty, at which point I'll call a function which returns me to my program.

This is a wretched flow in my head though, and will require some pretty hefty changes in the logic of my program... not to mention using some state variables which were previously unnecessary... and seeing as before I was able to achieve this with a straight flow, I'm sure there's a way to do it... annnnnnnny hints?

-Rob
 
load the form with modal.

i.e frm1.load vbModal

Your code would be

Sub doStuffOpenFormDoDLAndContinue()


'Some code
'Some more code
frm2.load vbModal
'Code runs after frm2 is unloaded
'The execution of this code will not continue until frm1 is
'unloaded
end sub
 
CORRECTED:

load the form with modal.

i.e frm1.load vbModal

Your code would be

Sub doStuffOpenFormDoDLAndContinue()


'Some code
'Some more code
frm2.load vbModal
'Code runs after frm2 is unloaded
'The execution of this code will not continue until frm2 is
'unloaded
end sub

 
May I suggest that you add the following loop immediately after the Inet.execute call. Borrowing from and adding to rorubin's code:

Code:
Private Sub Command1_Click()
    ' Init the progressbar
    ProgressBar1.Value = 0
    ' Set the status label to ""
    Label1.Caption = ""
    ' The Execute method takes four optional parameters,
    ' of which we will use two, url and operation.
    ' The url parameter is a string value with any valid
    ' url and the operation can be GET, HEAD, POST, PUT.
    ' We will use GET in this example, which gives us the
    ' data of the specified url. Information about the
    ' others can be found if you follow one of the
    ' specified external links in the end of the article.
    Inet1.Execute Text1.Text, "GET"
Code:
   Do While Inet1.StillExecuting
      DoEvents
   Loop
Code:
End Sub
Good Luck
--------------
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top