Librerie client FTP Java riviste

Immaginiamo una situazione in cui vogliamo scrivere un'applicazione Java pura che deve scaricare file da un computer remoto che esegue un server FTP. Vogliamo anche filtrare i download sulla base delle informazioni sui file remoti come nome, data o dimensione.

Sebbene sia possibile, e forse divertente, scrivere un gestore di protocollo per FTP da zero, farlo è anche difficile, lungo e potenzialmente rischioso. Dal momento che preferiamo non spendere tempo, fatica o denaro per scrivere un gestore da soli, preferiamo invece riutilizzare un componente software esistente. E molte biblioteche sono disponibili sul World Wide Web. Con una libreria client FTP, il download di un file può essere scritto in Java semplicemente come:

FTPClient ftpClient = nuovo FTPClient (); ftpClient.connect ("ftp.foo.com", "user01", "pass1234"); ftpClient.download ("C: \\ Temp \\", "README.txt"); // Eventualmente altre operazioni qui ... ftpClient.disconnect ();

Cercare una libreria client FTP Java di qualità che soddisfi le nostre esigenze non è così semplice come sembra; può essere piuttosto doloroso. Ci vuole del tempo per trovare una libreria client FTP Java. Quindi, dopo aver trovato tutte le librerie esistenti, quale selezioniamo? Ogni biblioteca risponde a esigenze diverse. Le biblioteche sono di qualità ineguale e il loro design differisce fondamentalmente. Ognuno offre una serie diversa di funzionalità e utilizza diversi tipi di gergo per descriverle.

Pertanto, la valutazione e il confronto delle librerie client FTP può risultare difficile e confuso. Riutilizzare i componenti esistenti è un processo lodevole, ma in questo caso iniziare può essere scoraggiante. E questo è un peccato: dopo aver scelto una buona libreria FTP, il resto è routine.

Questo articolo mira a rendere il processo di selezione breve, facile e utile. Per prima cosa elenco tutte le librerie client FTP disponibili. Quindi definisco e descrivo un elenco di criteri rilevanti che le biblioteche dovrebbero affrontare in qualche modo. Infine, presento una matrice panoramica che offre una rapida visione di come le librerie si sovrappongono l'una contro l'altra. Tutte queste informazioni forniscono tutto ciò di cui abbiamo bisogno per prendere una decisione rapida, affidabile e duratura.

Supporto FTP in JDK

La specifica di riferimento per FTP è Request for Comments: 959 (RFC959). Sun Microsystems fornisce un'implementazione RFC959 nel JDK, ma è interna, non documentata e non viene fornita alcuna fonte. Sebbene RFC959 si trovi nell'ombra, in realtà è il back-end di un'interfaccia pubblica che implementa RFC1738, la specifica URL, come illustrato nella Figura 1.

Un'implementazione di RFC1738 è offerta come standard nel JDK. Fa un lavoro ragionevole per le operazioni di trasferimento FTP di base. È pubblico e documentato e viene fornito il codice sorgente. Per usarlo, scriviamo quanto segue:

URL url = nuovo URL ("ftp: // user01: [email protected]/README.txt; type = i"); URLConnection urlc = url.openConnection (); InputStream è = urlc.getInputStream (); // Per scaricare OutputStream os = urlc.getOutputStream (); // Caricare

Il supporto client FTP in JDK segue rigorosamente la raccomandazione standard, ma presenta diversi aspetti negativi:

  • Fondamentalmente differisce dalle librerie client FTP di terze parti; questi implementano RFC959 anziché RFC1738.
  • RFC959 è implementato nella maggior parte degli strumenti client FTP desktop. Molti programmatori Java utilizzano questi strumenti per connettersi ai server FTP. Per una questione di gusti, questi strumenti molto probabilmente preferiscono librerie simili a RFC959.
  • Le classi URLe URLConnectionaprono solo flussi di comunicazione. La biblioteca offre supporto Sun non dritto per strutturare le risposte del server FTP prime in più utilizzabile oggetti Java come String, File, RemoteFile, o Calendar. Quindi dobbiamo scrivere più codice solo per scrivere dati in un file o per sfruttare un elenco di directory.
  • Come spiegato nella sezione 3.2.5 di RFC1738, "Ottimizzazione", gli URL FTP richiedono che la connessione (di controllo) si chiuda dopo ogni operazione. Questo è uno spreco e non efficiente per il trasferimento di molti piccoli file. Inoltre, i server FTP estremamente restrittivi possono considerare un tale sovraccarico di comunicazione come un attacco o un abuso di rete dannoso e negare ulteriore servizio.
  • Infine, manca di diverse funzioni utili.

Per tutti o uno qualsiasi di questi motivi, è preferibile utilizzare una libreria di terze parti. La sezione seguente elenca le alternative di terze parti disponibili.

Confronto tra biblioteche

L'elenco seguente delinea le librerie che confronto in questo articolo. Tutti seguono la specifica FTP di riferimento. Di seguito, menziono il nome del provider e il nome della libreria (in corsivo). Risorse include collegamenti a ciascun sito Web del prodotto. Per avviare rapidamente l'uso della libreria, menziono anche la classe principale del client FTP.

  1. JScape, iNet Factory :com.jscape.inet.ftp.Ftp
  2. / n software, IP * Funziona :ipworks.Ftp
  3. Enterprise Distributed Technologies, Java FTP Client Library :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. The Jakarta Project, 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, API JavaFTP :com.cqs.ftp.FTP
  10. Bea Petrovicova, jFTP :cz.dhl.ftp.Ftp
  11. Il progetto Globus, Java CoG Kit :org.globus.io.ftp.FTPClient

Appunti:

  • Al momento della stesura di questo documento, IBM sta valutando l'idoneità di offrire la sua alphaWorks FTP Bean Suite sul suo sito web. Per ora, il download è chiuso per tutti gli utenti.
  • Jakarta Commons / Net è un sostituto immediato di Savarese NetComponents, che non è più sviluppato.
  • JavaShop JNetBeans sembra essere stato abbandonato. Al momento in cui scrivo, il sito è offline da più di un mese e non ho mai ricevuto risposta alle mie richieste di supporto.

Criteri

Finora ho introdotto il contesto e ho elencato le librerie disponibili. Ora elenco i criteri rilevanti rispetto ai quali verrà valutata ciascuna libreria. Enumererò i possibili valori per ogni criterio, insieme all'abbreviazione (in grassetto ) utilizzata nella matrice di confronto finale.

Supporto del prodotto

Le librerie forniscono supporto agli utenti attraverso la documentazione del prodotto, Javadoc compilati, codice di esempio e un'applicazione di esempio che può includere commenti e spiegazioni. È possibile offrire ulteriore supporto agli utenti tramite forum, mailing list, un indirizzo email di contatto o un sistema di tracciamento dei bug online. Il software / n offre un supporto completo a un costo aggiuntivo.

La motivazione di un amministratore dell'assistenza è un fattore importante per un supporto rapido. Gli amministratori dell'assistenza possono essere:

  • Un individuo volontario ( I )
  • Un gruppo volontario ( G )
  • Un'entità professionale pagata per fornire supporto ( P )

Licenza

Per i progetti commerciali, una licenza del prodotto è una questione importante da considerare dall'inizio. Alcune librerie possono essere ridistribuite liberamente in prodotti commerciali e altre no. Ad esempio, GPL (GNU General Public License) è una licenza forte e limitante, mentre la licenza del software Apache richiede solo una menzione nei prodotti ridistribuiti.

Le licenze commerciali limitano il numero di workstation di sviluppo che programmano con la libreria, ma la distribuzione della libreria stessa non è limitata.

Per i progetti non commerciali, la licenza è più una questione di filosofia; un prodotto gratuito è apprezzabile.

Le licenze possono essere:

  • Commerciale ( 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.

La maggior parte delle librerie supporta connessioni attive e passive: la connessione passiva è utile quando il client si trova dietro un firewall che inibisce le connessioni in entrata a porte superiori. RFC1579 discute questa funzionalità firewall-friendly in modo più dettagliato. La documentazione di alcuni prodotti fa riferimento alle connessioni attive e passive rispettivamente come PORTe PASVcomandi.

Trasferimento parallelo

In un'applicazione desktop, quando un trasferimento inizia nel thread singolo principale, tutto si blocca. Alcune librerie gestiscono automaticamente il ciclo degli eventi per i trasferimenti paralleli in thread separati, quindi non dobbiamo creare e gestire i nostri thread.

Supporto delle specifiche JavaBean

Alcune librerie implementano la specifica JavaBean. La conformità JavaBean consente la programmazione visiva, che è presente nei principali IDE Java.