Programmering

Java FTP-klientbiblioteker gennemgået

Lad os forestille os en situation, hvor vi vil skrive en ren Java-applikation, der skal downloade filer fra en fjerncomputer, der kører en FTP-server. Vi ønsker også at filtrere downloads på basis af eksterne filoplysninger som navn, dato eller størrelse.

Selvom det er muligt og måske sjovt at skrive en protokolhåndterer til FTP fra bunden, er det også svært, langt og potentielt risikabelt at gøre det. Da vi hellere ikke bruger tid, kræfter eller penge på at skrive en handler alene, foretrækker vi i stedet at genbruge en eksisterende softwarekomponent. Og mange biblioteker er tilgængelige på World Wide Web. Med et FTP-klientbibliotek kan download af en fil skrives i Java så enkelt som:

FTPClient ftpClient = ny FTPClient (); ftpClient.connect ("ftp.foo.com", "user01", "pass1234"); ftpClient.download ("C: \ Temp \", "README.txt"); // Til sidst andre operationer her ... ftpClient.disconnect (); 

Det er ikke så simpelt at se efter et Java FTP-klientbibliotek af høj kvalitet, der matcher vores behov; det kan være ret smertefuldt. Det tager lidt tid at finde et Java FTP-klientbibliotek. Derefter, efter at vi har fundet alle de eksisterende biblioteker, hvilken vælger vi? Hvert bibliotek imødekommer forskellige behov. Bibliotekerne er ulige i kvalitet, og deres design adskiller sig fundamentalt. Hver tilbyder forskellige sæt funktioner og bruger forskellige typer jargon til at beskrive dem.

Evaluering og sammenligning af FTP-klientbiblioteker kan således vise sig at være vanskelig og forvirrende. At genbruge eksisterende komponenter er en prisværdig proces, men i dette tilfælde kan det være afskrækkende at starte. Og det er en skam: efter at have valgt et godt FTP-bibliotek, er resten rutinemæssig.

Denne artikel sigter mod at gøre denne udvælgelsesproces kort, let og umagen værd. Jeg viser først alle tilgængelige FTP-klientbiblioteker. Derefter definerer jeg og beskriver en liste over relevante kriterier, som bibliotekerne skal adressere på en eller anden måde. Endelig præsenterer jeg en oversigtsmatrix, der giver et hurtigt overblik over, hvordan bibliotekerne stabler op mod hinanden. Alle disse oplysninger giver alt, hvad vi har brug for for at træffe en hurtig, pålidelig og langvarig beslutning.

FTP-understøttelse i JDK

Referencespecifikationen for FTP er anmodning om kommentarer: 959 (RFC959). Sun Microsystems leverer en RFC959-implementering i JDK, men den er intern, udokumenteret og der er ingen kilde til rådighed. Mens RFC959 ligger i skyggen, er det faktisk bagenden af ​​en offentlig grænseflade, der implementerer RFC1738, URL-specifikationen, som illustreret i figur 1.

En implementering af RFC1738 tilbydes som standard i JDK. Det gør et rimeligt job til grundlæggende FTP-overførselsoperationer. Det er offentligt og dokumenteret, og kildekoden leveres. For at bruge det skriver vi følgende:

URL url = ny URL ("ftp: // user01: [email protected]/README.txt; type = i"); URLConnection urlc = url.openConnection (); InputStream er = urlc.getInputStream (); // For at downloade OutputStream os = urlc.getOutputStream (); // For at uploade 

FTP-klientsupport i JDK følger nøje standardanbefalingen, men den har flere ulemper:

  • Det adskiller sig fundamentalt fra tredjeparts FTP-klientbiblioteker; disse implementerer RFC959 snarere end RFC1738.
  • RFC959 er implementeret i de fleste desktop FTP-klientværktøjer. Mange Java-programmører bruger disse værktøjer til at oprette forbindelse til FTP-servere. Som et spørgsmål om smag foretrækker disse værktøjer sandsynligvis RFC959-lignende biblioteker.
  • Det URL og URL-forbindelse klasser åbner kun streams til kommunikation. Sun-biblioteket tilbyder ingen direkte support til strukturering af de rå FTP-serverresponser i mere brugbare Java-objekter som Snor, Fil, RemoteFile, eller Kalender. Så vi er nødt til at skrive mere kode bare for at skrive data i en fil eller for at udnytte en katalogoversigt.
  • Som forklaret i afsnit 3.2.5 i RFC1738, "Optimering", kræver FTP-URL'er, at (kontrol) forbindelsen lukkes efter hver operation. Dette er spild og ikke effektivt til overførsel af mange små filer. Ydermere kan ekstremt restriktive FTP-servere betragte en sådan kommunikationsomkostning som et ondt netværksangreb eller misbrug og nægte yderligere service.
  • Endelig mangler det flere nyttige funktioner.

Af alle eller nogen af ​​disse grunde foretrækkes det at bruge et tredjepartsbibliotek. Det følgende afsnit viser de tilgængelige tredjepartsalternativer.

Bibliotek sammenligning

Listen nedenfor viser de biblioteker, jeg sammenligner i hele denne artikel. De følger alle FTP-referencespecifikationen. Nedenfor nævner jeg udbydernavnet og bibliotekets navn (i kursiv). Ressourcer inkluderer links til hvert produkts websted. For at starte start af biblioteksbrug nævner jeg også FTP-klientens vigtigste klasse.

  1. JScape, iNet-fabrik: com.jscape.inet.ftp.Ftp
  2. / n software, IP * fungerer: ipworks.Ftp
  3. Virksomhedsdistribuerede teknologier, Java FTP-klientbibliotek: 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. Jakarta-projektet, Jakarta Commons / Net: org.apache.commons.net.ftp.FTPClient
  7. JavaShop JNetBeans: jshop.jnet.FTPClient
  8. Sol, JDK: sun.net.ftp.FtpClient
  9. Florent Cueto, JavaFTP API: com.cqs.ftp.FTP
  10. Bea Petrovicova, jFTP: cz.dhl.ftp.Ftp
  11. Globus-projektet, Java CoG-sæt: org.globus.io.ftp.FTPClient

Bemærkninger:

  • På dette tidspunkt vurderer IBM egnetheden af ​​at tilbyde sin alphaWorks FTP Bean Suite på sit websted. Indtil videre er download lukket for alle brugere.
  • Jakarta Commons / Net er en drop-in erstatning for Savarese NetComponents, som ikke længere er udviklet.
  • JavaShop JNetBeans synes at være forladt. På tidspunktet for denne skrivning har webstedet været offline i mere end en måned, og jeg har aldrig fået svar på mine supportanmodninger.

Kriterier

Indtil videre har jeg introduceret konteksten og listet de tilgængelige biblioteker. Nu viser jeg de relevante kriterier, som hvert bibliotek vil blive vurderet efter. Jeg opregner mulige værdier for hvert kriterium sammen med forkortelsen (i fremhævet) anvendt i den endelige sammenligningsmatrix.

Produktsupport

Bibliotekerne yder support til brugerne gennem produktdokumentation, kompileret Javadocs, prøvekode og et eksempel på et program, der kan indeholde kommentarer og forklaringer. Yderligere support kan tilbydes brugere via fora, mailinglister, en kontakt-e-mail-adresse eller et online bug tracking system. / n software tilbyder omfattende support mod et ekstra gebyr.

En supportadministrators motivation er en vigtig faktor for hurtig support. Supportadministratorer kan være:

  • En frivillig person (jeg)
  • En frivillig gruppe (G)
  • En professionel enhed betalt for at yde support (P)

Licens

For kommercielle projekter er en produktlicens et vigtigt spørgsmål at overveje fra starten. Nogle biblioteker kan frit distribueres i kommercielle produkter, og andre ikke. For eksempel er GPL (GNU General Public License) en stærk, begrænsende licens, mens Apache-softwarelicensen kun kræver en omtale i omfordelede produkter.

Kommercielle licenser begrænser antallet af udviklingsarbejdsstationer, der programmerer med biblioteket, men distributionen af ​​selve biblioteket er ikke begrænset.

For ikke-kommercielle projekter er licens mere et spørgsmål om filosofi; et gratis produkt er mærkbart.

Licenser kan være:

  • Kommerciel (C)
  • GPL (G)
  • Ledig (F); dog kontrollere en gratis licens for begrænsninger

Nogle biblioteksudbydere leverer alternative, mindre restriktive licenser efter behov.

Kildekode angivet

Et softwarebibliotek med sort kasse med lukket kilde kan være irriterende. At have kildekode kan være mere behageligt af følgende grunde:

  • Når du fejler udførelse af applikationskode, kan det være en hjælp at forstå biblioteksadfærd ved at træde ind i bibliotekodekilden
  • Kildekoden har nyttige kommentarer
  • Kildekoden kan hurtigt justeres for at matche særlige behov
  • Eksempler på kildekode kan være inspirerende

Alder

Biblioteker er blevet testet, fejlretet og understøttet siden deres første offentlige udgivelse. Da versionsnummerering varierer mellem biblioteker, baserer jeg dette kriterium på året for den tidligste offentlige udgivelse.

Kataloglisteunderstøttelse

Hentning af ekstern filinformation (navn, størrelse, dato) fra serveren er vigtig i de fleste applikationer. FTP-protokollen tilbyder NLST kommando til kun at hente filnavnene; det NLST kommando er eksplicit designet til at blive udnyttet af programmer. Det LISTE kommando tilbyder flere filoplysninger; som RFC959 bemærker, "Da oplysningerne om en fil kan variere meget fra system til system, kan disse oplysninger være vanskelige at bruge automatisk i et program, men kan være ret nyttige for en menneskelig bruger." Ingen anden standardmetode henter filoplysninger; derfor prøver klientbiblioteker at udnytte LISTE respons. Men dette er ikke en let opgave: da der ikke findes nogen autoritativ anbefaling til LISTE svarformat, FTP-servere har vedtaget forskellige formater:

  • Unix stil: drwxr-xr-x 1 bruger01 ftp 512 29. jan 23:32 prog
  • Alternativ Unix-stil: drwxr-xr-x 1 bruger01 ftp 512 29. januar 1997 prog
  • Alternativ Unix-stil: drwxr-xr-x 1 1 1 512 29. jan 23:32 prog
  • Et symbolsk link i Unix-stil: lrwxr-xr-x 1 bruger01 ftp 512 29. jan 23:32 prog -> prog2000
  • Underlig Unix-stil (intet mellemrum mellem bruger og gruppe): drwxr-xr-x 1 usernameftp 512 29. jan 23:32 prog
  • MS-DOS-stil: 01-29-97 23:32 prog
  • Macintosh-stil: drwxr-xr-x mappe 0 29. jan 23:32 prog
  • OS / 2-stil: 0 DIR 01-29-97 23:32 PROG

Unix-stil, derefter MS-DOS-stil, er de mest udbredte formater.

Java FTP-klientbiblioteker forsøger at forstå og automatisk registrere så mange formater som muligt. Derudover tilbyder de forskellige alternativer til håndtering af uventede formatsvar:

  • En yderligere metode, der returnerer et rå FTP-svar som en streng (S)
  • En yderligere metode, der returnerer en samling rå strenge, en streng pr. Linje / fil (C)
  • En ramme, der understøtter stikbare parsere (P)

De fleste biblioteker analyserer LISTE svar og struktur rå filinformation i Java-objekter. For eksempel med JScape iNet Factory henter og udnytter følgende kode filoplysninger, der er modtaget i en katalogoversigt:

java.util.Enumeration filer = ftpClient.getDirListing (); mens (files.hasMoreElements ()) {FtpFile ftpFile = (FtpFile) files.nextElement (); System.out.println (ftpFile.getFilename ()); System.out.println (ftpFile.getFilesize ()); // osv. andre nyttige metoder er beskrevet i Javadoc} 

Afsnittet "Løsninger til resterende problemer" behandler yderligere katalogoversigter.

Hentning af tidsstempel

I mange tilfælde er vi interesserede i en fjernfils seneste tidsstempel til ændring. Desværre introducerer ingen RFC en standard FTP-kommando for at hente disse oplysninger. Der findes to de facto metoder:

  1. Hent disse oplysninger fra LISTE svar ved at analysere serversvaret. Desværre, som du lærte i det foregående afsnit, LISTE svaret varierer mellem FTP-servere, og oplysningerne om tidsstempel er undertiden ufuldstændige. I Unix-formatet opstår der upræcision, når fjernfilen er mere end et år gammel: kun datoen og året, men ikke timer eller minutter, er angivet.
  2. Brug ikke-standard MDTM kommando, der specifikt henter en fjernfils sidste tidsstempel til ændring. Desværre implementerer ikke alle FTP-servere denne kommando.

Et indviklet alternativ til MDTM kommandostøtte er at sende en rå MDTM kommandere og analysere svaret. De fleste biblioteker giver en metode til at sende en rå FTP-kommando, noget som:

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

En anden mulig bekymring er, at FTP-servere returnerer tidsinformation i GMT (Greenwich Mean Time). Hvis serverens tidszone er kendt bortset fra FTP-kommunikation, vises java.util.TimeZone.getOffset () metode kan hjælpe med at justere en dato mellem tidszoner. Se JDK-dokumentation for yderligere information om denne metode.

Afsnittet "Løsninger til resterende problemer" behandler yderligere hentning af filens tidsstempel.

Firewalls

Typisk placeres en firewall mellem et privat virksomhedsnetværk og et offentligt netværk såsom Internettet. Adgang styres fra det private netværk til det offentlige netværk, men adgang nægtes fra det offentlige netværk til det private netværk.

Sokker er en offentligt tilgængelig protokol, der er udviklet til brug som en firewall-gateway til Internettet. JDK understøtter sokker 4 og sokker 5 fuldmagter, som kan styres af nogle af bibliotekerne. Som et alternativ kan JVM-kommandolinjen indstille Socks-proxyparametre: java -DsocksProxyPort = 1080 -DsocksProxyHost = socks.foo.com -Djava.net.socks.username = user01 -Djava.net.socks.password = pass1234 ...

Et andet almindeligt alternativ til Socks proxy-support er at "socksify" det underliggende TCP / IP-lag på klientmaskinen. Et produkt som Hummingbird kan gøre det job.

JDK understøtter også HTTP-tunneller. Disse udbredte proxyer tillader ikke FTP-uploads. / n software's IP * Works giver dig mulighed for at indstille HTTP-tunnelparametre.

De fleste biblioteker understøtter både aktive og passive forbindelser: passiv forbindelse er nyttig, når klienten er bag en firewall, der forhindrer indgående forbindelser til højere porte. RFC1579 diskuterer denne firewall-venlige funktionalitet mere detaljeret. Nogle produkters dokumentationer henviser til aktive og passive forbindelser som HAVN og PASV kommandoer, henholdsvis.

Parallel overførsel

I en desktop-applikation, når en overførsel starter i hovedtråden, fryser alt. Nogle biblioteker servicerer automatisk hændelsessløjfen til parallelle overførsler i separate tråde, så vi ikke behøver at oprette og administrere vores egne tråde.

JavaBean-specifikationsunderstøttelse

Nogle biblioteker implementerer JavaBean-specifikationen. JavaBean-overholdelse tillader visuel programmering, som findes i større Java IDE'er.