Seite 1 von 1

Datei stückweise hochladen? (FTP)

Verfasst: 14.01.2007 02:18
von Frogger
Eine Datei normal hochladen ist ja kein problem mit FtpPutFile_(...)
aber wie bekommt man es hin sie stückweise hochzuladen?
Es wäre auch ok wenn man den Fortschritt bei FtpPutFile_(...) abfragen könnte.
(Es geht mir eigentlich nur darum das in einer Progressbar anzeigen zu lassen)
Geht das überhaupt mit API und wenn ja wie?

PS: Suche hat nichts ergeben^^

Verfasst: 14.01.2007 02:38
von AND51
Das hat irgendetwas mit "Append" zu tun. Der FTP Befehl, um Daten an eine Datei anzufügen, heißt "APPE" (Kurzform) bzw. "APPEND" (Langform).

Vielleicht findest du ja in der Richtung etwas.

Wichtig: Der Server kann das hinzufügen von Daten an eine Datei verbieten (kann also APPEND verweigern), je nachdem, welche Rechte gesetzt worden sind.

Verfasst: 14.01.2007 15:51
von Frogger
Hmm also hab leider nichts gefunden wie man das mit API und APPEND machen kann.
Oder wie man den Progress von FtpPutFile_(...) anzapfen kann find ich auch nichts.

Hat evtl. jemand sowas schon gemacht und kann mir den Code geben?

Verfasst: 14.01.2007 17:49
von Vallan
Dann muss man es wohl mit einem Normalem
PB Netzwerk klient und SendNetworkString() machen, Leider kenne ich die syntax nicht (Genausowenig header etc)... aber es gib sicher kompetentere leute hier.

Verfasst: 14.01.2007 23:07
von tobe
hi Frogger,

ich hab dir mal nen beispielcode zusammengeschustert:

Code: Alles auswählen

EnableExplicit
#INTERNET_SERVICE_FTP = 1
#INTERNET_OPEN_TYPE_DIRECT = 1
#FTP_TRANSFER_ASCII = 1
#FTP_TRANSFER_BINARY = 2
#INTERNET_STATUS_REQUEST_SENT = 31
#INTERNET_STATUS_HANDLE_CREATED = 60
#INTERNET_STATUS_HANDLE_CLOSING = 70

Structure FILEDATA
  ServerName$
  UserName$
  Password$
  LocalFile$
  RemoteFile$
  Port.l
  hInternet.l
  hConnect.l
  StartTime.l
  TotalByteLength.q
  TotalBytesTransferred.q
EndStructure

Procedure InternetStatusCallback(hInternet, dwContext, dwInternetStatus, lpvStatusInformation, dwStatusInformationLength)
  Protected *File.FILEDATA, time
  Select dwInternetStatus
    Case #INTERNET_STATUS_REQUEST_SENT
      If dwContext
        *File.FILEDATA = dwContext
        *File\TotalBytesTransferred + PeekL(lpvStatusInformation)
      EndIf
    Case #INTERNET_STATUS_HANDLE_CREATED
      Debug "Handle created: " + Str(PeekL(lpvStatusInformation))
      If dwContext
        *File.FILEDATA = dwContext
        *File\StartTime = ElapsedMilliseconds()
        *File\TotalBytesTransferred = 0
      EndIf
    Case #INTERNET_STATUS_HANDLE_CLOSING
      If dwContext
        *File.FILEDATA = dwContext
        Debug StrF((*File\TotalBytesTransferred / 1024) / ((ElapsedMilliseconds() - *File\StartTime) / 1000),3) + " kb/s"
      EndIf
      Debug "Handle closed"
  EndSelect
  ;Debug "hInternet: " + Str(hInternet)
  ;Debug "dwContext: " + Str(dwContext)
  ;Debug "dwInternetStatus: " + Str(dwInternetStatus)
  ;Debug "lpvStatusInformation: " + Str(lpvStatusInformation)
  ;Debug "dwStatusInformationLength: " + Str(dwStatusInformationLength)
EndProcedure

Procedure FtpPutFile(*File.FILEDATA)
  If FtpPutFile_(*File\hConnect, *File\LocalFile$, *File\RemoteFile$, #FTP_TRANSFER_BINARY, *File)
    Debug "Ok - " + Str(*File\TotalBytesTransferred) + " / " + Str(*File\TotalByteLength)
  Else
    Debug "FtpPutFile Error !"
  EndIf
EndProcedure

Procedure CopyWindow(*File.FILEDATA)
  Protected time, OldSize, Window, CounterID, ProgressID, kBytesID, Thread, Timer, Timer1000
  *File\TotalByteLength = FileSize(*File\LocalFile$)
  If *File\TotalByteLength > -1
    *File\hInternet = InternetOpen_("FTP", #INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0)
    If *File\hInternet
      InternetSetStatusCallback_(*File\hInternet, @InternetStatusCallback())
      *File\hConnect = InternetConnect_(*File\hInternet, *File\ServerName$, *File\Port, *File\UserName$, *File\Password$, #INTERNET_SERVICE_FTP, 0, 0)
      If *File\hConnect
        Window = OpenWindow(#PB_Any, 0, 0, 300, 100, "", #PB_Window_ScreenCentered)
        If Window And CreateGadgetList(WindowID(Window))
          CounterID =  TextGadget        (#PB_Any, 10,  10, 280,  20, "0 / 0", #PB_Text_Center)
          ProgressID = ProgressBarGadget (#PB_Any, 10,  30, 280,  30, 0, 1000, #PB_ProgressBar_Smooth)
          kBytesID =   TextGadget        (#PB_Any, 10,  70, 280,  20, "0 kb/s", #PB_Text_Center)
          Thread = CreateThread(@FtpPutFile(), *File)
          Repeat
            time = ElapsedMilliseconds()
            If time >= Timer
              Timer = time + 100
              SetGadgetText(CounterID, StrQ(*File\TotalBytesTransferred) + " / " + StrQ(*File\TotalByteLength))
              SetGadgetState(ProgressID, Int((1000 / *File\TotalByteLength) * *File\TotalBytesTransferred))
            EndIf
            If time >= Timer1000
              Timer1000 = time + 1000
              SetGadgetText(kBytesID, StrF(((*File\TotalBytesTransferred - OldSize) / 1024), 1) + " kb/s")
              OldSize = *File\TotalBytesTransferred
            EndIf
            Select WaitWindowEvent(30)
              Case #PB_Event_CloseWindow
                Break
              Case #NULL
                If Thread
                  If WaitThread(Thread, 5)
                    Break
                  EndIf
                EndIf
            EndSelect
          ForEver
          CloseWindow(Window)
        Else
          MessageRequester("", "Window Error !")
        EndIf
      Else
        MessageRequester("", "Connect Error !")
      EndIf
      InternetSetStatusCallback_(*File\hInternet, 0)
      InternetCloseHandle_(*File\hInternet)
    EndIf
  Else
    MessageRequester("", "File Error !")
  EndIf
EndProcedure

Define File.FILEDATA
File\ServerName$ = "server"
File\Port = 21
File\UserName$ = "anonymous"
File\Password$ = "none@home.de"
File\LocalFile$ = "C:\testfile"
File\RemoteFile$ = "testfile"
CopyWindow(File)

Verfasst: 15.01.2007 11:12
von Vallan
uff, Ist das ein ganzer FTP server? (Zum hochladen von dataien)
Und wo kann man die hearer nachschauen?

ICh kann das her jetzt nicht testen (Schule).

Verfasst: 15.01.2007 13:28
von Shardik
@tobe:

Sehr schönes Beispiel, danke schön. Allerdings werden die meisten wohl Texte übertragen wollen, sodaß man in der Zeile
If FtpPutFile_(*File\hConnect, *File\LocalFile$, *File\RemoteFile$, #FTP_TRANSFER_BINARY, *File)
#FTP_TRANSFER_BINARY durch #FTP_TRANSFER_ASCII ersetzen sollte. Ansonsten hat Dein Beispiel sogar auf Anhieb auch beim FTP-Upload auf einen IBM-Mainframe funktioniert. Klasse!

Ein Code-Beispiel für das Anhängen an eine schon vorhandene Server-Datei mit APPE/APPEND habe ich übrigens schon einmal im englischen Forum veröffentlicht:
http://www.purebasic.fr/english/viewtopic.php?t=22984

Verfasst: 15.01.2007 18:51
von Frogger
Danke für eure Antworten.
Und vielen Dank tobe :allright:
Das ist genau das was ich gesucht habe.
Ich übertrage nur Dateien (kein Text) und es funktionierte auf anhieb perfekt.