Salut à tous,
j'aimerai pouvoir reprendre le téléchargement d'un fichier interrompu, pour celà j'utilise la commande InternetSetFilePointer_(hURL, bytes_reprise, 0, #FILE_BEGIN ,0), ça marche mais le problème est que mon programme se bloque jusqu'à que la commande se positionne sur la partie restante à télécharger du fichier (défini par ma variable bytes_reprise), c'est comme s'il téléchargeait toute la partie précédante et ça peut prendre du temps sur des fichiers à 10mo par exemple.
Quelqu'un sait comment résoudre ce problème svp ?
Reprise d'un téléchargement interrompu.
Reprise d'un téléchargement interrompu.
Dernière modification par Atomo le jeu. 22/mai/2008 20:33, modifié 1 fois.
Re: InternetSetFilePointer
prenez l'habitude de poster un code, pour montrer le problemeAtomo a écrit :Salut à tous,
j'aimerai pouvoir reprendre le téléchargement d'un fichier interrompu, pour celà j'utilise la commande InternetSetFilePointer_(hURL, bytes_reprise, 0, #FILE_BEGIN ,0), ça marche mais le problème est que mon programme se bloque jusqu'à que la commande se positionne sur la partie restante à télécharger du fichier (défini par ma variable bytes_reprise), c'est comme s'il téléchargeait toute la partie précédante et ça peut prendre du temps sur des fichiers à 10mo par exemple.
Quelqu'un sait comment résoudre ce problème svp ?
bien souvent l'erreur viens de l'architecture même de vos codes...
les membres qui donnent des réponses, le font en prenant sur leur temps libre , donc, la moindre des choses etant de faciliter leur travail bénévole

venir écrire un message qui dit :"au secours ça marche pas"
sans code ne sert a rien !!
c'est comme si moi je te posait la question ,
j'ai fait un programme de gestion, et je ne comprends pas pourquoi une de mes fenetre ne s'ouvre pas ...
t'imagine ta tete en lisant ça ?
voila voila ..

Tu as raison désolé.
Je vous ai fait un exemple, ça télécharge la démo de purebasic (11mo) dans le répertoire où vous lancerez ce programme.
Lancez une fois ce programme puis appuyez sur Annuler quand vous voulez puis relancez le, ça devrait reprendre le téléchargement mais avec le bug.
Je vous ai fait un exemple, ça télécharge la démo de purebasic (11mo) dans le répertoire où vous lancerez ce programme.
Lancez une fois ce programme puis appuyez sur Annuler quand vous voulez puis relancez le, ça devrait reprendre le téléchargement mais avec le bug.
Code : Tout sélectionner
Enumeration
#Window_0
#pourcentage
#ProgressBar_0
#Boutton_0
EndEnumeration
Global Quit.b
Global Close.b
Procedure update()
DownloadURL.s = "http://www.purebasic.com/download/PureBasic_Demo.exe"
DownloadFilename.s= "PureBasic_Demo.exe"
Protected hInet, hURL, Bytes
Protected BufferLength = 2048, Buffer.s = Space(BufferLength)
Protected Url.s = DownloadURL.s
Protected Filename.s = DownloadFilename.s
Protected File
Protected CurrentSize, PreviousSize, FileSize, time, BytesPerSecond
Protected Domain.s, String.s, i, BufferLengthWas = BufferLength
Protected hInetCon, hHttpOpenRequest, iretval
hInet = InternetOpen_("Downloader",0,0,0,0)
hURL = InternetOpenUrl_(hInet,Url.s,0,0,$80000000,0)
;Get filesize
Domain.s = StringField(Url.s,3,"/")
hInetCon = InternetConnect_(hInet,Domain.s,80,#Null,#Null,3,0,0)
If hInetCon
hHttpOpenRequest = HttpOpenRequest_(hInetCon,"HEAD",ReplaceString(Url.s,"http://"+Domain.s+"/",""),#Null,#Null,0,$80000000,0)
If hHttpOpenRequest
iretval = HttpSendRequest_(hHttpOpenRequest,#Null,0,0,0)
If iretval
HttpQueryInfo_(hHttpOpenRequest,19,@Buffer.s,@BufferLength,0) ;changes the buffer length
String.s = PeekS(@Buffer.s,BufferLength): BufferLength = BufferLengthWas
If Trim(String.s) = "200"
HttpQueryInfo_(hHttpOpenRequest,22,@Buffer.s,@BufferLength,0)
String.s = PeekS(@Buffer.s,BufferLength): BufferLength = BufferLengthWas
If FindString(String.s,"Content-Length:",1)
i = FindString(String.s,"Content-Length:",1) + Len("Content-Length:")
String.s = Mid(String.s,i,Len(String.s)-i)
FileSize = Val(Trim(String.s))/1024
EndIf
EndIf
EndIf
EndIf
EndIf
;Download file and update status
If hURL
taille_fichier = FileSize("PureBasic_Demo.exe")
If taille_fichier > 0 ;le fichier existe déjà alors reprise
CurrentSize = taille_fichier
File = OpenFile(#PB_Any, "PureBasic_Demo.exe") ;ouverture du fichier
FileSeek(File, CurrentSize) ;on place le pointeur d'écriture là où on s'était arreté
InternetSetFilePointer_(hURL, CurrentSize, 0, #FILE_BEGIN ,0)
Else ;nouveau téléchargement
File = CreateFile(#PB_Any,Filename.s)
EndIf
If File
time = ElapsedMilliseconds()
While InternetReadFile_(hURL,@Buffer.s,BufferLength,@Bytes) And Bytes > 0
If Quit = #True
Break
EndIf
WriteData(File,@Buffer.s,Bytes)
CurrentSize + Bytes
Pourcentage.f = ((CurrentSize/1024)/FileSize)*100
SetGadgetState(#ProgressBar_0, Pourcentage)
If time < ElapsedMilliseconds() - 1000
time = ElapsedMilliseconds()
BytesPerSecond = CurrentSize - PreviousSize
PreviousSize = CurrentSize
EndIf
Wend
CloseFile(File)
EndIf
EndIf
InternetCloseHandle_(hURL)
InternetCloseHandle_(hInetCon)
InternetCloseHandle_(hInet)
Close = #True
EndProcedure
If OpenWindow(#Window_0, 0, 0, 250, 105, "Download", #PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(#Window_0))
ProgressBarGadget(#ProgressBar_0, 21, 30, 207, 20, 0, 100)
ButtonGadget(#Boutton_0, 95, 77, 60, 20, "Annuler")
EndIf
EndIf
CreateThread(@update(), 0)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget ;si on est dans un gadget
Select EventGadget()
Case #Boutton_0
Quit = #True
EndSelect
EndSelect
Until Close = #True
End
dobro a raison c'est mieux avec le code source.
j'ai un peu regardé, c'est pas mal déjà ce que tu as fait.
j'ai corrigé deux trois trucs et ajouté deux trois MessageRequester / SetWindowTitle pour voir ce qui se passe.
à priori tout fonctionne bien.
quand tu dis que çà bloque, en fait çà bloque pas, il faut attendre un peu, qq secondes. chez moi dès fois j'attends 5 à 10 secondes (au niveau du premier appel à InternetReadFile) mais çà fini toujours par démarrer...
dis moi ce que çà donne :
j'ai un peu regardé, c'est pas mal déjà ce que tu as fait.
j'ai corrigé deux trois trucs et ajouté deux trois MessageRequester / SetWindowTitle pour voir ce qui se passe.
à priori tout fonctionne bien.
quand tu dis que çà bloque, en fait çà bloque pas, il faut attendre un peu, qq secondes. chez moi dès fois j'attends 5 à 10 secondes (au niveau du premier appel à InternetReadFile) mais çà fini toujours par démarrer...
dis moi ce que çà donne :
Code : Tout sélectionner
Import "shlwapi.lib"
StrFormatKBSizeA(Size.q, *BufStr, BufSize.l)
StrFormatByteSize64A(Size.q, *BufStr, BufSize.l)
EndImport
Procedure.s FormatKB(Size.q)
Protected BufStr.s{64}
If StrFormatKBSizeA(Size, @BufStr, 64)
ProcedureReturn PeekS(@BufStr, -1, #PB_Ascii)
EndIf
EndProcedure
Procedure.s FormatSize(Size.q)
Protected BufStr.s{64}
If StrFormatByteSize64A(Size, @BufStr, 64)
ProcedureReturn PeekS(@BufStr, -1, #PB_Ascii)
EndIf
EndProcedure
Enumeration
#Window_0
#pourcentage
#ProgressBar_0
#Boutton_0
EndEnumeration
Global Quit.b
Global Close.b
Procedure update()
DownloadURL.s = "http://www.purebasic.com/download/PureBasic_Demo.exe"
DownloadFilename.s= "PureBasic_Demo.exe"
Protected hInet, hURL, Bytes
Protected BufferLength = 2048, Buffer.s = Space(BufferLength)
Protected Url.s = DownloadURL.s
Protected Filename.s = DownloadFilename.s
Protected File
Protected CurrentSize, PreviousSize, FileSize, time, BytesPerSecond
Protected Domain.s, String.s, i, BufferLengthWas = BufferLength
Protected hInetCon, hHttpOpenRequest, iretval
hInet = InternetOpen_("Downloader",0,0,0,0)
hURL = InternetOpenUrl_(hInet,Url.s,0,0,$80000000,0)
;Get filesize
Domain.s = StringField(Url.s,3,"/")
SetWindowTitle(0, "InternetConnect_")
hInetCon = InternetConnect_(hInet,Domain.s,80,#Null,#Null,3,0,0)
If hInetCon
SetWindowTitle(0, "HttpOpenRequest")
hHttpOpenRequest = HttpOpenRequest_(hInetCon,"HEAD",ReplaceString(Url.s,"http://"+Domain.s+"/",""),#Null,#Null,0,$80000000,0)
If hHttpOpenRequest
SetWindowTitle(0, "HttpSendRequest")
iretval = HttpSendRequest_(hHttpOpenRequest,#Null,0,0,0)
If iretval
SetWindowTitle(0, "HttpQueryInfo")
HttpQueryInfo_(hHttpOpenRequest,19,@Buffer.s,@BufferLength,0) ;changes the buffer length
String.s = PeekS(@Buffer.s,BufferLength): BufferLength = BufferLengthWas
If Trim(String.s) = "200"
HttpQueryInfo_(hHttpOpenRequest,22,@Buffer.s,@BufferLength,0)
String.s = PeekS(@Buffer.s,BufferLength): BufferLength = BufferLengthWas
;MessageRequester("debug", string)
If FindString(String.s,"Content-Length:",1)
i = FindString(String.s,"Content-Length:",1) + Len("Content-Length:")
String.s = Trim(Mid(String.s,i))
FileSize = Val(String.s)
EndIf
EndIf
EndIf
EndIf
EndIf
;Download file and update status
If hURL
SetWindowTitle(0, "FileSize")
taille_fichier = FileSize("PureBasic_Demo.exe")
If taille_fichier > 0 ;le fichier existe déjà alors reprise
CurrentSize = taille_fichier
If CurrentSize = FileSize
MessageRequester("Information", "Le fichier existe déjà et semble complet !", #MB_ICONINFORMATION)
Quit = #True
Else
message.s
message = "Le fichier existe déjà !" + Chr(10)
message + "Taille du fichier à reprendre: " + FormatSize(CurrentSize) + Chr(10)
message + "Taille du fichier à télécharger: " + FormatSize(FileSize) + Chr(10) + Chr(10)
message + "Oui pour reprendre, Non pour télécharger à nouveau, ou Annuler."
Select MessageRequester("Information", Message, #PB_MessageRequester_YesNoCancel | #MB_ICONQUESTION)
Case #IDYES
File = OpenFile(#PB_Any, "PureBasic_Demo.exe") ;ouverture du fichier
If File
SetWindowTitle(0, "FileSeek: " + FormatSize(CurrentSize))
FileSeek(File, CurrentSize) ;on place le pointeur d'écriture là où on s'était arreté
SetWindowTitle(0, "InternetSetFilePointer: " + FormatSize(CurrentSize))
If InternetSetFilePointer_(hURL, CurrentSize, 0, #FILE_BEGIN ,0) <> CurrentSize
MessageRequester("Erreur", "Echec de InternetSetFilePointer_()", #MB_ICONERROR)
EndIf
EndIf
Case #IDNO
CurrentSize = 0
Case #IDCANCEL
Quit = #True
EndSelect
EndIf
EndIf
If Not File
File = CreateFile(#PB_Any,Filename.s)
EndIf
If File
time = ElapsedMilliseconds()
SetWindowTitle(0, "InternetReadFile")
DisableGadget(#Boutton_0, #False)
While ( Quit = #False ) And ( InternetReadFile_(hURL,@Buffer.s,BufferLength,@Bytes) = #True ) And ( Bytes > 0 )
CurrentSize + WriteData(File,@Buffer.s,Bytes)
SetWindowTitle(0, "Téléchargement: " + FormatSize(CurrentSize) + " / " + FormatSize(FileSize))
Pourcentage.f = (CurrentSize/FileSize)*100
SetGadgetState(#ProgressBar_0, Pourcentage)
If time < ElapsedMilliseconds() - 1000
time = ElapsedMilliseconds()
BytesPerSecond = CurrentSize - PreviousSize
PreviousSize = CurrentSize
EndIf
Wend
DisableGadget(#Boutton_0, #True)
CloseFile(File)
EndIf
EndIf
SetWindowTitle(0, "InternetCloseHandle: hUrl")
InternetCloseHandle_(hURL)
SetWindowTitle(0, "InternetCloseHandle: hInetCon")
InternetCloseHandle_(hInetCon)
SetWindowTitle(0, "InternetCloseHandle: hInet")
InternetCloseHandle_(hInet)
Close = #True
EndProcedure
If OpenWindow(#Window_0, 0, 0, 250, 105, "Veuillez patienter...", #PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(#Window_0))
ProgressBarGadget(#ProgressBar_0, 21, 30, 207, 20, 0, 100)
ButtonGadget(#Boutton_0, 95, 77, 60, 20, "Annuler")
DisableGadget(#Boutton_0, #True)
EndIf
EndIf
CreateThread(@update(), 0)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget ;si on est dans un gadget
Select EventGadget()
Case #Boutton_0
SetWindowTitle(0, "Annulation...")
DisableGadget(#Boutton_0, #True)
Quit = #True
EndSelect
EndSelect
Until Close = #True
End
Merci pour le remaniement du code
Cependant le problème perssiste, si tu télécharges 200ko et que tu annules puis reprend, la reprise sera asser rapide, entre 1 et 5 secondes.
Par contre si tu télécharges 10 mo ça prend 1 minute, c'est comme si il téléchargeait le fichier à nouveau depuis le début.
Le temps d'attente pour initialiser la reprise est proportionnel au nombre de megas téléchargés, j'imagine même pas avec un fichier de 300mo.
edit : peut-être que le problème ne survient que chez moi ?

Cependant le problème perssiste, si tu télécharges 200ko et que tu annules puis reprend, la reprise sera asser rapide, entre 1 et 5 secondes.
Par contre si tu télécharges 10 mo ça prend 1 minute, c'est comme si il téléchargeait le fichier à nouveau depuis le début.
Le temps d'attente pour initialiser la reprise est proportionnel au nombre de megas téléchargés, j'imagine même pas avec un fichier de 300mo.

edit : peut-être que le problème ne survient que chez moi ?
oui 'Seeker' un fichier un fichier distant semble prendre du temps.
ca dépends peut être du serveur, tu as essayé sur un autre serveur ?
[EDIT]
je viens d'essayer avec le framework .net 3.5 (197mo)
http://download.microsoft.com/download/ ... etfx35.exe
et tu as raison, ce peut etre très long...
peut etre que le serveur ne supporte pas le seeking.... je sais pas.
ca dépends peut être du serveur, tu as essayé sur un autre serveur ?
[EDIT]
je viens d'essayer avec le framework .net 3.5 (197mo)
http://download.microsoft.com/download/ ... etfx35.exe
et tu as raison, ce peut etre très long...
peut etre que le serveur ne supporte pas le seeking.... je sais pas.
la doc msdn dit ceci :
intéressant... merci microsoft
et çà :InternetSetFilePointer Function
Sets a file position for InternetReadFile. This is a synchronous call; however, subsequent calls to InternetReadFile might block or return pending if the data is not available from the cache and the server does not support random access.
http://msdn.microsoft.com/en-us/library/ms918380.aspxInternetSetFilePointer cannot be used reliably if the content length is unknown.
intéressant... merci microsoft
