Java-FTP-Client-Bibliotheken überprüft

Stellen wir uns eine Situation vor, in der wir eine reine Java-Anwendung schreiben möchten, die Dateien von einem Remotecomputer herunterladen muss, auf dem ein FTP-Server ausgeführt wird. Wir möchten Downloads auch anhand von Remote-Dateiinformationen wie Name, Datum oder Größe filtern.

Obwohl es möglich ist und vielleicht Spaß macht, einen Protokollhandler für FTP von Grund auf neu zu schreiben, ist dies auch schwierig, langwierig und potenziell riskant. Da wir lieber keine Zeit, Mühe oder Geld damit verbringen, einen Handler selbst zu schreiben, ziehen wir es vor, eine vorhandene Softwarekomponente wiederzuverwenden. Im World Wide Web stehen zahlreiche Bibliotheken zur Verfügung. Mit einer FTP-Client-Bibliothek kann das Herunterladen einer Datei in Java so einfach geschrieben werden wie:

FTPClient ftpClient = neuer FTPClient (); ftpClient.connect ("ftp.foo.com", "user01", "pass1234"); ftpClient.download ("C: \\ Temp \\", "README.txt"); // Eventuell andere Operationen hier ... ftpClient.disconnect ();

Die Suche nach einer hochwertigen Java-FTP-Client-Bibliothek, die unseren Anforderungen entspricht, ist nicht so einfach, wie es scheint. es kann ziemlich schmerzhaft sein. Das Auffinden einer Java-FTP-Clientbibliothek dauert einige Zeit. Welche Bibliothek wählen wir dann aus, nachdem wir alle vorhandenen Bibliotheken gefunden haben? Jede Bibliothek erfüllt unterschiedliche Anforderungen. Die Bibliotheken sind qualitativ ungleich und ihre Designs unterscheiden sich grundlegend. Jedes bietet unterschiedliche Funktionen und verwendet unterschiedliche Jargontypen, um diese zu beschreiben.

Das Auswerten und Vergleichen von FTP-Client-Bibliotheken kann sich daher als schwierig und verwirrend erweisen. Die Wiederverwendung vorhandener Komponenten ist ein lobenswerter Prozess. In diesem Fall kann es jedoch entmutigend sein, mit dem Start zu beginnen. Und das ist eine Schande: Nach der Auswahl einer guten FTP-Bibliothek ist der Rest Routine.

Dieser Artikel soll diesen Auswahlprozess kurz, einfach und lohnenswert machen. Ich liste zuerst alle verfügbaren FTP-Client-Bibliotheken auf. Dann definiere und beschreibe ich eine Liste relevanter Kriterien, die die Bibliotheken auf irgendeine Weise ansprechen sollten. Abschließend präsentiere ich eine Übersichtsmatrix, die einen schnellen Überblick darüber gibt, wie sich die Bibliotheken gegeneinander stapeln. All diese Informationen bieten alles, was wir brauchen, um eine schnelle, zuverlässige und dauerhafte Entscheidung zu treffen.

FTP-Unterstützung in JDK

Die Referenzspezifikation für FTP lautet Anfrage für Kommentare: 959 (RFC959). Sun Microsystems bietet eine RFC959-Implementierung im JDK, diese ist jedoch intern, nicht dokumentiert und es wird keine Quelle bereitgestellt. Während RFC959 im Schatten liegt, ist es tatsächlich das Back-End einer öffentlichen Schnittstelle, die RFC1738, die URL-Spezifikation, implementiert, wie in Abbildung 1 dargestellt.

Eine Implementierung von RFC1738 wird standardmäßig im JDK angeboten. Es macht einen vernünftigen Job für grundlegende FTP-Übertragungsvorgänge. Es ist öffentlich und dokumentiert, und der Quellcode wird bereitgestellt. Um es zu benutzen, schreiben wir Folgendes:

URL url = neue URL ("ftp: // user01: [email protected]/README.txt; type = i"); URLConnection urlc = url.openConnection (); InputStream ist = urlc.getInputStream (); // Um ​​OutputStream herunterzuladen os = urlc.getOutputStream (); // Hochladen

Die Unterstützung von FTP-Clients in JDK folgt strikt der Standardempfehlung, hat jedoch mehrere Nachteile:

  • Es unterscheidet sich grundlegend von den FTP-Client-Bibliotheken von Drittanbietern. Diese implementieren RFC959 anstelle von RFC1738.
  • RFC959 ist in den meisten Desktop-FTP-Client-Tools implementiert. Viele Java-Programmierer verwenden diese Tools, um eine Verbindung zu FTP-Servern herzustellen. Aus Geschmacksgründen bevorzugen diese Tools höchstwahrscheinlich RFC959-ähnliche Bibliotheken.
  • Die Klassen URLund URLConnectionöffnen nur Streams für die Kommunikation. Die Sun - Bibliothek bietet keine gerade Unterstützung für die Strukturierung der rohen FTP - Server - Antworten in mehr nutzbare Java - Objekte wie String, File, RemoteFileoder Calendar. Wir müssen also mehr Code schreiben, um Daten in eine Datei zu schreiben oder eine Verzeichnisliste auszunutzen.
  • Wie in Abschnitt 3.2.5 von RFC1738, "Optimierung", erläutert, erfordern FTP-URLs, dass die (Steuer-) Verbindung nach jedem Vorgang geschlossen wird. Dies ist verschwenderisch und für die Übertragung vieler kleiner Dateien nicht effizient. Darüber hinaus können extrem restriktive FTP-Server einen solchen Kommunikationsaufwand als bösen Netzwerkangriff oder -missbrauch betrachten und weiteren Dienst verweigern.
  • Schließlich fehlen einige nützliche Funktionen.

Aus allen oder einem dieser Gründe ist die Verwendung einer Bibliothek eines Drittanbieters vorzuziehen. Im folgenden Abschnitt werden die verfügbaren Alternativen von Drittanbietern aufgeführt.

Bibliotheksvergleich

In der folgenden Liste sind die Bibliotheken aufgeführt, die ich in diesem Artikel vergleiche. Sie alle folgen der Referenz-FTP-Spezifikation. Im Folgenden erwähne ich den Anbieternamen und den Bibliotheksnamen (kursiv). Die Ressourcen enthalten Links zu jeder Produktwebsite. Um die Bibliotheksnutzung zu beschleunigen, erwähne ich auch die Hauptklasse des FTP-Clients.

  1. JScape, iNet Factory :com.jscape.inet.ftp.Ftp
  2. / n Software, IP * Funktioniert :ipworks.Ftp
  3. Verteilte Unternehmenstechnologien, Java FTP-Clientbibliothek :com.enterprisedt.net.ftp.FTPClient
  4. IBM alphaWorks, FTP Bean Suite :com.ibm.network.ftp.protocol.FTPProtocol
  5. SourceForge, JFtp :net.sf.jftp.net.FtpConnection
  6. Das Jakarta-Projekt, Jakarta Commons / Net :org.apache.commons.net.ftp.FTPClient
  7. JavaShop JNetBeans :jshop.jnet.FTPClient
  8. Sun, JDK :sun.net.ftp.FtpClient
  9. Florent Cueto, JavaFTP-API :com.cqs.ftp.FTP
  10. Bea Petrovicova, jFTP :cz.dhl.ftp.Ftp
  11. Das Globus-Projekt, Java CoG Kit :org.globus.io.ftp.FTPClient

Anmerkungen:

  • Zum Zeitpunkt dieses Schreibens prüft IBM die Eignung, seine alphaWorks FTP Bean Suite auf seiner Website anzubieten. Derzeit ist der Download für alle Benutzer geschlossen.
  • Jakarta Commons / Net ist ein Ersatz für Savarese NetComponents, der nicht mehr entwickelt wird.
  • JavaShop JNetBeans scheint aufgegeben worden zu sein. Zum Zeitpunkt dieses Schreibens war die Website mehr als einen Monat lang offline, und ich habe keine Antworten auf meine Supportanfragen erhalten.

Kriterien

Bisher habe ich den Kontext eingeführt und die verfügbaren Bibliotheken aufgelistet. Jetzt liste ich die relevanten Kriterien auf, anhand derer jede Bibliothek bewertet wird. Ich zähle mögliche Werte für jedes Kriterium zusammen mit der Abkürzung (in Fettdruck ) auf, die in der endgültigen Vergleichsmatrix verwendet wird.

Produkt Support

Die Bibliotheken bieten Benutzern Unterstützung durch Produktdokumentation, kompilierte Javadocs, Beispielcode und eine Beispielanwendung, die Kommentare und Erklärungen enthalten kann. Zusätzliche Unterstützung kann Benutzern über Foren, Mailinglisten, eine Kontakt-E-Mail-Adresse oder ein Online-Fehlerverfolgungssystem angeboten werden. / n Software bietet umfassenden Support gegen eine zusätzliche Gebühr.

Die Motivation eines Support-Administrators ist ein wichtiger Faktor für einen schnellen Support. Support-Administratoren können sein:

  • Eine freiwillige Person ( I )
  • Eine freiwillige Gruppe ( G )
  • Eine professionelle Einrichtung, die für die Bereitstellung von Unterstützung bezahlt wird ( P )

Lizenz

Bei kommerziellen Projekten ist eine Produktlizenz von Anfang an wichtig. Einige Bibliotheken können frei in kommerziellen Produkten verteilt werden, andere nicht. Beispielsweise ist GPL (GNU General Public License) eine starke, einschränkende Lizenz, während die Apache Software-Lizenz nur in neu verteilten Produkten erwähnt werden muss.

Kommerzielle Lizenzen begrenzen die Anzahl der mit der Bibliothek programmierten Entwicklungsarbeitsstationen, die Verteilung der Bibliothek selbst ist jedoch nicht eingeschränkt.

Bei nichtkommerziellen Projekten ist die Lizenz eher eine Frage der Philosophie. ein freies Produkt ist spürbar.

Lizenzen können sein:

  • Kommerziell ( C )
  • GPL ( G )
  • Free (F); however, check a free license for limitations

Some library providers provide alternate, less-restrictive licenses on demand.

Source code provided

A closed-sourced, black-box software library can be irritating. Having source code can be more comfortable for the following reasons:

  • When debugging application code execution, stepping into the library code source can help you understand library behavior
  • The source code has useful comments
  • Source code can be quickly tweaked to match special needs
  • Exemplary source code can be inspiring

Age

Libraries have been tested, debugged, and supported since their first public release. As version numbering varies among libraries, I base this criterion on the year of the earliest public release.

Directory listing support

Retrieving remote file information (name, size, date) from the server is important in most applications. The FTP protocol offers the NLST command to retrieve the file names only; the NLST command is explicitly designed to be exploited by programs. The LIST command offers more file information; as RFC959 notes, "Since the information on a file may vary widely from system to system, this information may be hard to use automatically in a program, but may be quite useful to a human user." No other standard method retrieves file information; therefore, client libraries try to exploit the LIST response. But this is not an easy task: since no authoritative recommendation is available for the LIST response format, FTP servers have adopted various formats:

  • Unix style: drwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog
  • Alternate Unix style: drwxr-xr-x 1 user01 ftp 512 Jan 29 1997 prog
  • Alternate Unix style: drwxr-xr-x 1 1 1 512 Jan 29 23:32 prog
  • A symbolic link in Unix style: lrwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog -> prog2000
  • Weird Unix style (no space between user and group): drwxr-xr-x 1 usernameftp 512 Jan 29 23:32 prog
  • MS-DOS style: 01-29-97 11:32PM prog
  • Macintosh style: drwxr-xr-x folder 0 Jan 29 23:32 prog
  • OS/2 style: 0 DIR 01-29-97 23:32 PROG

Unix style, then MS-DOS style, are the most widespread formats.

Java FTP client libraries try to understand and auto-detect as many formats as possible. In addition, they offer various alternatives for handling unexpected format answers:

  • An additional method returning a raw FTP response as one string (S)
  • An additional method returning a collection of raw strings, one string per line/file (C)
  • A framework supporting pluggable parsers (P)

Most libraries parse LIST responses and structure raw file information into Java objects. For example, with JScape iNet Factory, the following code retrieves and exploits file information received in a directory listing:

java.util.Enumeration files = ftpClient.getDirListing(); while (files.hasMoreElements()) { FtpFile ftpFile = (FtpFile) files.nextElement(); System.out.println(ftpFile.getFilename()); System.out.println(ftpFile.getFilesize()); // etc. other helpful methods are detailed in Javadoc } 

Section "Solutions for Remaining Problems" further considers directory listings.

Timestamp retrieval

In many cases, we are interested in a remote file's latest modification timestamp. Unfortunately, no RFC introduces a standard FTP command to retrieve this information. Two de facto methods exist:

  1. Retrieve this information from the LIST response by parsing the server answer. Unfortunately, as you learned in the previous section, the LIST response varies among FTP servers, and the timestamp information is sometimes incomplete. In the Unix format, imprecision occurs when the remote file is more than one year old: only the date and year, but not hours or minutes are given.
  2. Use the nonstandard MDTM command, which specifically retrieves a remote file's last modification timestamp. Unfortunately, not all FTP servers implement this command.

An intricate alternative to MDTM command support is to send a raw MDTM command and parse the response. Most libraries provide a method for sending a raw FTP command, something like:

String timeStampString = ftpClient.command("MDTM README.txt"); 

Another possible concern is that FTP servers return time information in GMT (Greenwich Mean Time). If the server time zone is known apart from FTP communication, the java.util.TimeZone.getOffset() method can help adjust a date between time zones. See JDK documentation for further information about this method.

Section "Solutions for Remaining Problems" further considers file timestamp retrieval.

Firewalls

Typically, a firewall is placed between a private enterprise network and a public network such as the Internet. Access is managed from the private network to the public network, but access is denied from the public network to the private network.

Socks is a publicly available protocol developed for use as a firewall gateway for the Internet. The JDK supports Socks 4 and Socks 5 proxies, which can be controlled by some of the libraries. As an alternative, the JVM command line can set the Socks proxy parameters: java -DsocksProxyPort=1080 -DsocksProxyHost=socks.foo.com -Djava.net.socks.username=user01 -Djava.net.socks.password=pass1234 ...

Another common alternative to Socks proxy support is to "socksify" the underlying TCP/IP layer on the client machine. A product like Hummingbird can do that job.

The JDK also supports HTTP tunnels. These widespread proxies do not allow FTP uploads. /n software's IP*Works allows you to set HTTP tunnel parameters.

Die meisten Bibliotheken unterstützen sowohl aktive als auch passive Verbindungen: Die passive Verbindung ist nützlich, wenn sich der Client hinter einer Firewall befindet, die eingehende Verbindungen zu höheren Ports verhindert. In RFC1579 wird diese Firewall-freundliche Funktionalität ausführlicher erläutert. Die Dokumentationen einiger Produkte beziehen sich auf aktive und passive Verbindungen als PORTbzw. PASVBefehle.

Parallele Übertragung

Wenn in einer Desktop-Anwendung eine Übertragung im einzelnen Hauptthread beginnt, friert alles ein. Einige Bibliotheken bedienen die Ereignisschleife automatisch für parallele Übertragungen in separaten Threads, sodass wir keine eigenen Threads erstellen und verwalten müssen.

Unterstützung für JavaBean-Spezifikationen

Einige Bibliotheken implementieren die JavaBean-Spezifikation. Die JavaBean-Konformität ermöglicht die visuelle Programmierung, die in den wichtigsten Java-IDEs enthalten ist.