FTP Synchronisieren

  • VB.NET

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von One-Soft.

    FTP Synchronisieren

    Hallöchen Leute :)

    ich bin neu im Forum, hab aber trotzdem schon fleißig gesucht, bevor ich hier meinen Senf dazu gebe.
    Also, mein Problem ist eigentlich, dass ich meinen FTP inklusive Ordnerstruktur auslesen und auf dem lokalen PC erstellen lassen möchte.
    Dazu hab ich natürlich die FTPLib gefunden, dabei kam das raus:

    VB.NET-Quellcode

    1. Private Sub Sync()
    2. Dim ftp As New FTP
    3. Dim remotePath As String = "/publish"
    4. Dim help As String
    5. Dim ftpDirectoryInfo As FTPDirectoryInfo = Nothing
    6. Dim ftpDirectoryInfos() As FTPDirectoryInfo = Nothing
    7. Dim ftpFileInfo As FTPFileInfo = Nothing
    8. Dim ftpFileInfos() As FTPFileInfo = Nothing
    9. ftp.Connect(host, username, password, 21)
    10. Try
    11. ftpDirectoryInfos = ftp.GetDirectoryInfos(remotePath, FTPLib.SearchOption.AllDirectories)
    12. For i As Integer = 0 To ftpDirectoryInfos.Length Step 1
    13. help = ftpFileInfos(i)
    14. Directory.CreateDirectory(Application.StartupPath & help)
    15. Next i
    16. Catch ex As Exception
    17. MsgBox(ex)
    18. End Try
    19. ftp.Disconnect()
    20. End Sub


    Das ganze starte ich dann mal und das Resultat ist ein Programm, dass mir "keine Rückmeldung" ausgibt. Ich dachte mir, vielleicht dauert es auch einfach nur lange .. Auch 34min später, nachdem ich meinen Spaß mit meinem Schlagzeug hatte hat sich absolut nichts getan. Vielleicht hab ich auch einfach nen dämlichen Fehler drin. Das hoffe ich mal, denn ich brauche langsam einen funktionierenden Code.
    Dazu muss ich allerdings jetzt mal sagen, dass ich dieses Programm kommerziell nutzen werde und das zu 100% und somit werde ich die FTPLib ohnehin nicht nutzen können, aber solange ich nicht-kommerziell programmiere, wäre es garnicht blöd schonmal was funktionierendes zu haben, was ich dann nutze, während ich mir was anderes überlege.

    Der andere Code, den ich dann komplett selbst geschrieben habe läuft soweit eigentlich, damit kann ich auch schön meine Progressbar mit einbinden, aber da ist das Problem, dass das Programm auch hier immer wieder für mehrere Sekunden einfach "keine Rückmeldung" ausgibt und manchmal stürzt es komplett hab. Jedoch funktioniert es erstmal.
    Der Code liest die Zeilen aus einer Textdatei aus. Jede Zeile ist dabei eine Datei die ich herunterladen möchte. Hier ignoriere ich die Ordnerstruktur und habe auf meinem FTP einfach alle Dateien erstmal im selben Ordner, weil ich möchte, dass das Programm wenigstens das kann. Das nächste Problem wäre es zwar dann, die Dateien in die 31 Ordner zu ordnen, aber das wäre dann was anderes. Hier der Code:

    VB.NET-Quellcode

    1. Dim localfile As String = Application.StartupPath & "\Datalist.txt"
    2. Const remoteFile As String = "/publish/Datalist.txt"
    3. Const host As String = "blablabla"
    4. Const username As String = "blablabla"
    5. Const password As String = "blablabla"
    6. Dim URI As String = host & remoteFile
    7. Dim ftp As System.Net.FtpWebRequest = CType(FtpWebRequest.Create(Uri), FtpWebRequest)
    8. ftp.Credentials = New System.Net.NetworkCredential(username, password)
    9. ftp.KeepAlive = False
    10. ftp.UseBinary = True
    11. ftp.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
    12. Using response As System.Net.FtpWebResponse = CType(ftp.GetResponse, System.Net.FtpWebResponse)
    13. Using responseStream As IO.Stream = response.GetResponseStream
    14. Using fs As New IO.FileStream(localfile, IO.FileMode.Create)
    15. Dim buffer(2047) As Byte
    16. Dim read As Integer = 0
    17. Do
    18. read = responseStream.Read(buffer, 0, buffer.Length)
    19. fs.Write(buffer, 0, read)
    20. Loop Until read = 0
    21. responseStream.Close()
    22. fs.Flush()
    23. fs.Close()
    24. End Using
    25. responseStream.Close()
    26. End Using
    27. response.Close()
    28. End Using
    29. End If


    So, das wars eigentlich. Vielleicht hat ja irgendjemand Zeit und Lust mir etwas zu helfen.
    Ich bedanke mich schonmal dafür und dafür, dass ihr bis hierhin gelesen habt.

    Schönen Sonntag :)
    Ohne mir deinen Code anzusehen:

    Die Vorgehensweise ist einfach. Du holst dir alle Daten aller Dateien und Ordner. Dann prüfst du die Size.
    Wenn Size=-1 dann ist es vrmtl. ein Ordner. Du holst dessen Namen, erstellst ihn und fährst fort. Wenn du das für alle gemacht hast, dann gehst du die Struktur des ersten Ordners immer weiter durch, speicherst aber dabei, welche Ordner du schon hast. Wenn du das so hin bekommst, müsstest du am Ende alle Ordner haben ;)

    [VB.NET] FtpWebRequest-Tutorial

    Grüße
    "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

    Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!
    Mal was zu deinem Code, ich bin da immer sehr ordentlich ;)

    1. In Zeile 6-9 bei den Deklarationen kannst du dir das Nothing sparen.

    2. Die For-Schleife in Zeile 16-19 kannst du durch eine For Each ersetzen, da du den Index direkt nicht benötigst:
    Und außerdem bei Pfadkombinationen solltest du IO.Path.Combine nutzen.

    VB.NET-Quellcode

    1. For Each help As String In ftpDirechtoryInfos
    2. Directory.CreateDirectory(IO.Path.Combine(Application.StartupPath,help))
    3. Next

    :)


    Dann würde ich mal debuggen und gucken was help in der ForEach für einen Wert hat.
    Vielleicht ist es jetzt ja auch schon behoben, weil bei dir als Parameter für CreateDirectory möööglicherweise kein ordentlicher Path angegeben wurde :whistling: :thumbsup:
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
    Zudem solltest du Passwörter in deiner Anwendung nicht im im Klartext als Variable speichern oder generell verwenden, denn dann sind sie einfach zu haben

    Gruß
    Youtube Info Library 2013 jetzt im Showroom.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „One-Soft“ ()

    ThePlexian schrieb:

    Mal was zu deinem Code, ich bin da immer sehr ordentlich ;)

    1. In Zeile 6-9 bei den Deklarationen kannst du dir das Nothing sparen.

    2. Die For-Schleife in Zeile 16-19 kannst du durch eine For Each ersetzen, da du den Index direkt nicht benötigst:
    Und außerdem bei Pfadkombinationen solltest du IO.Path.Combine nutzen.

    VB.NET-Quellcode

    1. For Each help As String In ftpDirechtoryInfos
    2. Directory.CreateDirectory(IO.Path.Combine(Application.StartupPath,help))
    3. Next

    :)


    Dann würde ich mal debuggen und gucken was help in der ForEach für einen Wert hat.
    Vielleicht ist es jetzt ja auch schon behoben, weil bei dir als Parameter für CreateDirectory möööglicherweise kein ordentlicher Path angegeben wurde :whistling: :thumbsup:



    Haha, ja ich bin bezüglich der For-Schleife sehr start Java geprägt aus der Schule und hab deswegen lieber diesen counter :P das for each hab ich noch nie so benutzt. naja, guck mal im anhang, das ist mein fehler :P

    das mit dem Passwort ist mein nächster punkt auf meiner To-Do, aber erstmal sollte der download funktionieren

    Edit: Im Prinzip ist help dazu da, den namen des Ordners zu speichern und dann zum Pfad hinzuzufügen
    Den Namen des Ordners sollte ich per: ftpDirectoryInfo.Name bekommen
    deswegen dürfte help theoretisch nicht in der schleife stehen, weil der Typ des Arrays ist ja ftpDirectoryInfo und nicht String


    Edit: okay, bin jetzt soweit:

    VB.NET-Quellcode

    1. For Each help As FTPDirectoryInfo In ftpDirectoryInfos
    2. Directory.CreateDirectory(IO.Path.Combine(Application.StartupPath, help.Name))
    3. Next


    aber help ist unterschlängelt: Fehler Die Variable "help" verbirgt eine Variable in einem einschließenden Block
    Bilder
    • Unbenannt.jpg

      138,66 kB, 1.207×747, 186 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „tooostaaa“ ()

    Okay, das Programm stürzt nach wie vor ab.
    Jetzt hab ich diesen Code der soweit auch funktioniert, aber eine Sache ist irgendwie scheiße:
    Während des Downloads ist absolut keine Chance irgendwas mit dem Programm zu machen.
    Es war doch irgendwie so, dass man dazu dann Asynchron downloaden muss, richtig ? wie mach ich das in diesem fall ?

    VB.NET-Quellcode

    1. Private Sub MetroButton1_Click(sender As System.Object, e As System.EventArgs) Handles MetroButton1.Click
    2. Label19.Text = getVersionLatest()
    3. Label17.Text = getVersionInstalled()
    4. MetroProgressbar1.Visible = True
    5. Dim path As String = Application.StartupPath & "\Datalist.txt"
    6. Dim objReader As New StreamReader(path)
    7. Dim sLine As String
    8. Dim value As Integer
    9. MetroProgressbar1.Maximum = CStr(System.IO.File.ReadAllLines(path).Count)
    10. Try
    11. Do
    12. sLine = objReader.ReadLine()
    13. If Not sLine Is Nothing Then
    14. DownLoadItem(sLine)
    15. value = value + 1
    16. End If
    17. MetroProgressbar1.Value = value
    18. Loop Until sLine Is Nothing
    19. objReader.Close()
    20. Catch ex As Exception
    21. MsgBox(ex)
    22. End Try
    23. End Sub
    24. Private Sub MetroButton4_Click(sender As System.Object, e As System.EventArgs) Handles MetroButton4.Click
    25. Label19.Text = getVersionLatest()
    26. Label17.Text = getVersionInstalled()
    27. End Sub
    28. Private Sub DownLoadItem(ByVal fileName As String)
    29. Dim request = WebRequest.Create(host & "/publish" & "/"c & fileName)
    30. request.Method = WebRequestMethods.Ftp.DownloadFile
    31. request.Credentials = New NetworkCredential(username, password)
    32. Dim dest = Path.Combine(Application.StartupPath, fileName)
    33. Using resp = request.GetResponse(), strmResp = resp.GetResponseStream, strmFile = New FileStream(dest, FileMode.Create)
    34. Dim buf(1023) As Byte
    35. Do
    36. Dim read = strmResp.Read(buf, 0, buf.Length)
    37. If read = 0 Then Exit Do
    38. strmFile.Write(buf, 0, read)
    39. Loop
    40. End Using
    41. End Sub


    Edit by Manschula: Unnötiges Vollzitat entfernt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Manschula“ ()

    Ich weiß nicht wie man Asynchron einen FTP-Server behandet, aber du könntest das ganze auch in einen Thread auslagern :)
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
    Okay, um erhlich zu sein hab ich keine Ahnung wie das geht.
    Ich hab bisher viele einfache Klassen und Windows Anwendungen geschrieben, die auch lokal super liefen und sowas nicht brauchten, weil sie nicht so leistungsfressend waren.
    Gibt es eine Art TuT dazu oder kannst du mir da helfen ?

    EDIT: Ich habs, alles gut.

    hat jetzt jemand noch ne idee, wie ich alle daten, die ich jetzt auf dem PC habe Optimal sortieren kann in den Ordner in dem ich sie will ?


    Edit by Manschula: Unnötiges Vollzitat entfernt

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Manschula“ ()

    ich habe eine Ordnerstruktur auf meinem FTP
    das ist ein Spiel und jede Datei hat seinen Platz in einem Ordner und die Shader haben zum Beispiel nichts bei der Launcher.exe zu suchen. Also hat alles seinen platz.
    Wenn ich alle Dateien in den /publish Ordner auf den FTP packe bekomme ich nun alles geladen, aber eben ohne Ordner und ohne Ordnerstruktur läuft das Spiel nicht.
    Wichtig ist, dass mein launcher später für alle potentiellen Spieler laufen soll und die wissen ja nicht wo welche datei hin muss und das soll alles vollautomatisch funktionieren inklusive Progressbar


    Edit by Manschula: Unnötiges Vollzitat entfernt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Manschula“ ()

    Dann musst du versuchen, herauszufinden, welche Ordner wie auf deinem Server liegen. Dann erstellst du diese auf deinem Pc.
    Youtube Info Library 2013 jetzt im Showroom.
    Was du machen könntest, wäre alle Dateien zu Zippen mit und sie dann entpacken lassen, wenn sie fertig heruntergeladen sind.
    Youtube Info Library 2013 jetzt im Showroom.
    also im prinzip alle auf dem ftp zippen, das zip runterladen und entpacken auf dem pc ?


    Edit by Manschula: Unnötiges Vollzitat entfernt

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Manschula“ ()

    Genau. Du läds das Spiel oder what ever auf deinen FTP Server hoch als ZIP-Archiv. Nach dem Download entpacks du das Archiv dahin, wo du es haben möchtest. So bleibt die Ordnerstruktur erhalten.

    [EDIT]:Hier gibt es was dazu, vlt. kannst du damit etwas anfangen:

    [VB.NET] Zip-Datei ohne externe Tools entpacken.
    Youtube Info Library 2013 jetzt im Showroom.
    Okay, perfekt

    nur:

    VB.NET-Quellcode

    1. Try
    2. Do
    3. sLine = objReader.ReadLine()
    4. If Not sLine Is Nothing Then
    5. DownLoadItem(sLine)
    6. value = value + 1
    7. End If
    8. MetroProgressbar1.Value = value
    9. Loop Until sLine Is Nothing
    10. objReader.Close()
    11. Catch ex As Exception
    12. MsgBox(ex)
    13. End Try
    14. End Sub


    du siehst ja dadrin die "MetroProgressbar1"
    Dort wird sie erhöht und "läuft voll"
    Wie bekomm ich das mit der .zip dann hin ? Weil ich möchte ja gerne, dass ich ne Progressbar habe, die mir den Download anzeigt
    Du läds das Archiv via Webclient herunter. Im DownloadProgressChanged Event von dem Webclient, kannst du den Status abfragen:

    VB.NET-Quellcode

    1. Private Sub wc_DownloadProgressChanged(sender As Object, e As Net.DownloadProgressChangedEventArgs) Handles wc.DownloadProgressChanged
    2. MetroProgressbar1.Value = e.ProgressPercentage
    3. End Sub
    Youtube Info Library 2013 jetzt im Showroom.
    Okay, also
    soweit läuft jetzt alles, der Download läuft perfekt, das unzippen führt zum Absturz und die Progressbar ist nicht drin

    VB.NET-Quellcode

    1. Private Sub DownLoadItem(ByVal fileName As String)
    2. Try
    3. Dim request = WebRequest.Create(host & "/publish" & "/"c & fileName)
    4. request.Method = WebRequestMethods.Ftp.DownloadFile
    5. request.Credentials = New NetworkCredential(username, password)
    6. Dim dest = Path.Combine(Application.StartupPath, fileName)
    7. Using resp = request.GetResponse(), strmResp = resp.GetResponseStream, strmFile = New FileStream(dest, FileMode.Create)
    8. Dim buf(2048) As Byte
    9. Do
    10. Dim read = strmResp.Read(buf, 0, buf.Length)
    11. If read = 0 Then Exit Do
    12. strmFile.Write(buf, 0, read)
    13. Loop
    14. End Using
    15. If Not Directory.Exists("GameData") Then
    16. Directory.CreateDirectory("GameData")
    17. End If
    18. Catch ex As Exception
    19. MsgBox(ex)
    20. End Try
    21. UnZip(fileName)
    22. End Sub
    23. Sub UnZip(ByVal filename As String)
    24. Dim sc As New Shell32.Shell()
    25. Dim output As Shell32.Folder = sc.NameSpace("GameData")
    26. Dim input As Shell32.Folder = sc.NameSpace(filename)
    27. output.CopyHere(input.Items, 4)
    28. MsgBox("Your game has successfully been installed")
    29. Thread.Abort()
    30. End Sub


    Ich hab es mit WebClient versucht, aber da gabs wieder fehler über fehler und das hier funktioniert ja, nur leider eben ohne progressbar
    irgendeine idee ?

    das unzippen will auch nicht :(

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tooostaaa“ ()