Reprise d'un téléchargement interrompu.

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Atomo
Messages : 207
Inscription : lun. 17/sept./2007 12:27

Reprise d'un téléchargement interrompu.

Message par Atomo »

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 ?
Dernière modification par Atomo le jeu. 22/mai/2008 20:33, modifié 1 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: InternetSetFilePointer

Message par Backup »

Atomo 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 ?
prenez l'habitude de poster un code, pour montrer le probleme
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 :D

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 .. :)
Atomo
Messages : 207
Inscription : lun. 17/sept./2007 12:27

Message par Atomo »

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.

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
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

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 :

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
Image
Atomo
Messages : 207
Inscription : lun. 17/sept./2007 12:27

Message par Atomo »

Merci pour le remaniement du code :D
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 ?
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

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.
Image
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

la doc msdn dit ceci :
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.
et çà :
InternetSetFilePointer cannot be used reliably if the content length is unknown.
http://msdn.microsoft.com/en-us/library/ms918380.aspx



intéressant... merci microsoft :roll:
Image
Atomo
Messages : 207
Inscription : lun. 17/sept./2007 12:27

Message par Atomo »

Bitcomet me dit bien que la démo de purebasic supporte la fonction résume :?
Répondre