FTP und SIZE-Methode

  • VB.NET

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von us4711.

    FTP und SIZE-Methode

    Es gibt Wochenenden, da wäre man lieber im Regen mit der Familie spazierengegangen ...

    Ich spiel' zur Zeit ein wenig mit einem externen FTP-Server herum, das ist ein komplett neues Gebiet für mich. Und ich bin stolz. Mit dem alten Goggle & Try+Error habe ich verstanden, wie die verscheidenen Komponenten zusammenwirken: URI, Credentials, verschiedene FTP-Methoden. Und dann, ja dann ...

    Hier der Code, der für alle WebRequestMethods.Ftp.xxx-Methoden funktioniert:

    VB.NET-Quellcode

    1. Public Function FileLastModified() As DateTime
    2. Dim Request As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(UriFile), System.Net.FtpWebRequest)
    3. With Request
    4. .Credentials = New System.Net.NetworkCredential(Username, Password)
    5. .Method = WebRequestMethods.Ftp.GetDateTimestamp
    6. .KeepAlive = False
    7. .UseBinary = True
    8. .Timeout = System.Threading.Timeout.Infinite
    9. End With
    10. Dim Response As FtpWebResponse = Nothing
    11. Try
    12. Response = CType(Request.GetResponse, FtpWebResponse)
    13. Return Response.LastModified
    14. Catch ex As Exception
    15. Throw
    16. Finally
    17. Response.Close()
    18. End Try
    19. End Function


    Und dann kam WebRequestMethods.Ftp.GetFileSize. Und das bringt den Fehler:
    Der Remoteserver hat einen Fehler zurückgegeben: (550) Datei nicht verfügbar (z.B. nicht gefunden oder kein Zugriff)..
    FileZilla sagt mir aber, das die Datei sehr wohl da ist, zumal der FTP-Server bei FileLastModified() mit dieser Datei wunschgemäss antwortet.

    Der Code generiert den Fehler an der Stelle:
    Response = CType(Request.GetResponse, FtpWebResponse)

    VB.NET-Quellcode

    1. Public Function FileContentLength() As Long
    2. Dim Request As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(UriFile), System.Net.FtpWebRequest)
    3. With Request
    4. .Credentials = New System.Net.NetworkCredential(Username, Password)
    5. .Method = WebRequestMethods.Ftp.GetFileSize
    6. .KeepAlive = False
    7. .UseBinary = True
    8. .Timeout = System.Threading.Timeout.Infinite
    9. End With
    10. Dim Response As FtpWebResponse = Nothing
    11. Try
    12. Response = CType(Request.GetResponse, FtpWebResponse)
    13. Return Response.ContentLength
    14. Catch ex As Exception
    15. Throw
    16. Finally
    17. Response.Close()
    18. End Try
    19. End Function


    Googeln erbrachte nichts Verwertbares, zumindest habe ich nichts Verwertbares verstanden.

    Vielleicht gibt es ja hier Informationen, die weiterführen ... vielen Dank im Voraus.
    Nunja, keine Lösung, aber ein workaround ...

    VB.NET-Quellcode

    1. Public Function FileContentLength() As Long
    2. Dim Request As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(UriFile), System.Net.FtpWebRequest)
    3. With Request
    4. .Credentials = New System.Net.NetworkCredential(Username, Password)
    5. .Method = WebRequestMethods.Ftp.ListDirectoryDetails
    6. .KeepAlive = False
    7. .UseBinary = True
    8. .Timeout = System.Threading.Timeout.Infinite
    9. End With
    10. Using Response As FtpWebResponse = CType(Request.GetResponse, FtpWebResponse)
    11. Using Reader As New IO.StreamReader(Response.GetResponseStream())
    12. ' Server liefert nur eine Zeile
    13. Dim EntryLine As String = Reader.ReadLine
    14. ' Enthaltene doppelte Leerzeichen entfernen
    15. While EntryLine.Contains(" ")
    16. EntryLine = EntryLine.Replace(" ", " ")
    17. End While
    18. ' Die enthaltenen Felder sind nunmehr durch Leerzeichen getrennt.
    19. Dim EntryArray = EntryLine.Split(CChar(" "))
    20. ' das Array entält nun folgende Informationen im String-Format:
    21. ' (0) = Attribute
    22. ' (1) = Objektart. 1= File, 2=Directory
    23. ' (2) = Username
    24. ' (3) = Host
    25. ' (4) = ContentLength
    26. ' (5) = Monat
    27. ' (6) = Tag
    28. ' (7) = Uhrzeit, wenn Lastmodified.year = ServerDatum.year, sonst lastModified.year
    29. ' (8) = Dateiname bzw. Directory-Name
    30. If EntryArray(1) = "1" Then ' Nur Dateien, Directories nicht berücksichtigen
    31. Return CLng(EntryArray(4))
    32. Else
    33. Return -1
    34. End If
    35. End Using
    36. End Using
    37. End Function


    Das Zeitverhalten ist i.O. Nachdem ich die Struktur der Server-Response evaluiert hatte, wuchsen natürlich neue Begehrlichkeiten. Wäre es denn nicht schön, auf die dargestellte Weise eine echte FtpServerFileInfo, bzw. ServerFtpDirectoryInfo zu entwickeln?
    Wäre auch ohne Weiteres möglich, wenn die Inhalte der Felder 5,6 und 7 (Datum/Zeit) konsistent wären, was Sie aber leider NICHT sind. Auf diesem Wege ist das LastModified-Datum MIT Zeitangabe für eine Datei, die in einem älteren Jahr als dem aktuellen erstellt wurde, nicht ermittelbar. So ist ein zusätzlicher Aufruf von FileLastModified erforderlich, was das Laufzeitverhalten doch sehr verschlechtert. Wenn es unter unseren Experten Anregungen gibt, wäre ich sehr dankbar.