ספריות לקוח Java FTP נבדקו

בואו נדמיין מצב בו אנו רוצים לכתוב יישום Java טהור שחייב להוריד קבצים ממחשב מרוחק שמריץ שרת FTP. אנו רוצים גם לסנן הורדות על בסיס מידע על קבצים מרוחקים כמו שם, תאריך או גודל.

למרות שאפשר, ואולי כיף, לכתוב מטפל פרוטוקולים ל- FTP מאפס, זה גם קשה, ארוך ועלול להיות מסוכן. מכיוון שאנחנו מעדיפים לא לבזבז זמן, מאמץ או כסף בכדי לכתוב מטפל בעצמנו, אנו מעדיפים לעשות שימוש חוזר ברכיב תוכנה קיים. והרבה ספריות זמינות באינטרנט. באמצעות ספריית לקוח FTP ניתן להוריד הורדת קובץ ב- Java בפשטות כמו:

FTPClient ftpClient = FTPClient חדש (); ftpClient.connect ("ftp.foo.com", "user01", "pass1234"); ftpClient.download ("C: \\ Temp \\", "README.txt"); // בסופו של דבר פעולות אחרות כאן ... ftpClient.disconnect ();

לחפש ספריית לקוח Java FTP איכותית שתואמת את הצרכים שלנו אינה פשוטה כמו שהיא נראית; זה יכול להיות די כואב. לוקח קצת זמן למצוא ספריית לקוח Java FTP. ואז, לאחר שנמצא את כל הספריות הקיימות, איזו מהן אנו בוחרים? כל ספרייה נותנת מענה לצרכים שונים. הספריות אינן שוות באיכותן, ועיצוביהן שונים במהותם. כל אחד מהם מציע סט תכונות אחר ומשתמש בסוגים שונים של ז'רגון לתיאורם.

לפיכך, הערכה והשוואה של ספריות לקוח FTP יכולות להיות קשה ומבלבלות. שימוש חוזר ברכיבים קיימים הוא תהליך ראוי לשבח, אך במקרה זה, התחלה יכולה להיות מרתיעה. וחבל: לאחר בחירת ספריית FTP טובה, השאר הוא שגרתי.

מאמר זה נועד להפוך את תהליך הבחירה לקצר, קל וכדאי. ראשית אני מפרט את כל ספריות לקוח ה- FTP הזמינות. ואז אני מגדיר ומתאר רשימה של קריטריונים רלוונטיים שהספריות צריכות להתייחס אליהם בצורה כלשהי. לסיום, אני מציג מטריצת סקירה המספקת תצוגה מהירה על האופן שבו הספריות מסתדרות זו בזו. כל המידע הזה מספק את כל מה שאנחנו צריכים כדי לקבל החלטה מהירה, אמינה וארוכת טווח.

תמיכה ב- FTP ב- JDK

מפרט הייחוס ל- FTP הוא בקשה להערות: 959 (RFC959). סאן מיקרוסיסטמס מספקת יישום RFC959 ב- JDK, אך הוא פנימי, ללא תיעוד, ואין מקור. בעוד ש- RFC959 טמון בצללים, זהו למעשה הקצה האחורי של ממשק ציבורי המיישם את RFC1738, מפרט ה- URL, כפי שמודגם באיור 1.

יישום של RFC1738 מוצע כסטנדרט ב- JDK. זה עושה עבודה סבירה עבור פעולות העברת FTP בסיסיות. הוא ציבורי ומתועד, וקוד המקור מסופק. כדי להשתמש בו, אנו כותבים את הדברים הבאים:

URL url = URL חדש ("ftp: // user01: [email protected]/README.txt; type = i"); URLConnection urlc = url.openConnection (); InputStream הוא = urlc.getInputStream (); // להורדת OutputStream os = urlc.getOutputStream (); // להעלות

תמיכה בלקוחות FTP ב- JDK מקפידה על ההמלצה הסטנדרטית, אך יש לה כמה חסרונות:

  • זה שונה באופן מהותי מספריות לקוח ה- FTP של צד שלישי; אלה מיישמים את RFC959 ולא את RFC1738.
  • RFC959 מיושם ברוב כלי FTP- לקוח שולחניים. מתכנתי Java רבים משתמשים בכלים אלה כדי להתחבר לשרתי FTP. כעניין של טעם, ככל הנראה כלים אלה מעדיפים ספריות דמויי RFC959.
  • URLו URLConnectionכיתות בלבד זרמים פתוחים לתקשורת. הצעות ספריית השמש לא ישר תמיכת מבנה תגובות שרת FTP גלמו לתוך Java שמיש יותר אובייקטים כמו String, File, RemoteFile, או Calendar. אז עלינו לכתוב קוד נוסף רק כדי לכתוב נתונים לקובץ או לנצל רישום ספריות.
  • כפי שהוסבר בסעיף 3.2.5 ב- RFC1738, "אופטימיזציה", כתובות אתרי FTP מחייבות את חיבור (השליטה) לאחר כל פעולה. זה בזבזני ולא יעיל להעברת קבצים קטנים רבים. יתר על כן, שרתי FTP מגבילים ביותר עשויים להחשיב תקורה כזו כמתקפת רשת או שימוש לרעה ולהכחיש שירות נוסף.
  • לבסוף, חסרים לו כמה תכונות שימושיות.

מכל הסיבות הללו או מכל אחת מהן, עדיף להשתמש בספריית צד שלישי. החלק הבא מפרט את החלופות הזמינות של צד שלישי.

השוואת ספרייה

הרשימה שלהלן מתארת ​​את הספריות שאני משווה לאורך מאמר זה. כולם עוקבים אחר מפרט ה- FTP. להלן אני מזכיר את שם הספק ואת שם הספרייה (בנטוי). המשאבים כוללים קישורים לכל אתר מוצר. כדי להשתמש בספריה, אני מזכיר גם את מחלקת לקוח ה- FTP הראשית.

  1. JScape, מפעל iNet :com.jscape.inet.ftp.Ftp
  2. תוכנת / n, IP * עובד :ipworks.Ftp
  3. טכנולוגיות מבוזרות ארגוניות, ספריית לקוח FTP של Java :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. פרויקט ג'קרטה, ג'קרטה Commons / Net :org.apache.commons.net.ftp.FTPClient
  7. JavaShop JNetBeans :jshop.jnet.FTPClient
  8. שמש, JDK :sun.net.ftp.FtpClient
  9. פלורנט קואטו, JavaFTP API :com.cqs.ftp.FTP
  10. ביה פטרוביקובה , jFTP :cz.dhl.ftp.Ftp
  11. פרויקט גלובוס, ערכת Java CoG :org.globus.io.ftp.FTPClient

הערות:

  • בעת כתיבת שורות אלה יבמ בוחנת את ההתאמה להציע את alphaWorks FTP Bean Suite באתר האינטרנט שלה. לעת עתה ההורדה סגורה לכל המשתמשים.
  • ג'קרטה קומונס / נט היא תחליף טיפה ל- NetComponents של Savarese, שאינו מפותח יותר.
  • נראה כי JavaShop JNetBeans ננטש. בזמן כתיבת שורות אלה האתר לא מקוון יותר מחודש, ומעולם לא קיבלתי תשובות לבקשות התמיכה שלי.

קריטריונים

עד כה הצגתי את ההקשר ורשמתי את הספריות הזמינות. כעת אני מפרט את הקריטריונים הרלוונטיים שלפיהם תוערך כל ספרייה. אני מונה ערכים אפשריים עבור כל קריטריון, יחד עם קיצור ( מודגש ) המשמש במטריצת ההשוואה הסופית.

תמיכת מוצר

הספריות מספקות תמיכה למשתמשים באמצעות תיעוד מוצרים, Javadocs מקובצים, קוד לדוגמה ויישום לדוגמא שיכול לכלול הערות והסברים. ניתן להציע תמיכה נוספת למשתמשים באמצעות פורומים, רשימות תפוצה, כתובת דוא"ל ליצירת קשר או מערכת מעקב מקוונת אחר באגים. תוכנת / n מציעה תמיכה רחבה בתשלום נוסף.

המוטיבציה של מנהל התמיכה היא גורם חשוב לתמיכה מהירה. מנהלי תמיכה יכולים להיות:

  • אדם מרצון ( אני )
  • קבוצה התנדבותית ( G )
  • גורם מקצועי ששולם עבור מתן תמיכה ( P )

רישיון

עבור פרויקטים מסחריים, רישיון מוצר הוא עניין חשוב שיש להתחשב בו מההתחלה. ניתן לחלק באופן חופשי ספריות במוצרים מסחריים ואחרות לא. לדוגמא, GPL (רישיון ציבורי כללי של GNU) הוא רישיון חזק ומגביל, בעוד שרישיון תוכנת Apache דורש אזכור רק במוצרים המחולקים מחדש.

רישיונות מסחריים מגבילים את מספר תכנות תחנות העבודה בפיתוח עם הספרייה, אך הפצת הספרייה עצמה אינה מוגבלת.

בפרויקטים שאינם מסחריים, רישיון הוא יותר עניין של פילוסופיה; מוצר חינמי ניתן להערכה.

הרישיונות יכולים להיות:

  • מסחרי ( C )
  • GPL ( G )
  • חינם ( F ); עם זאת, בדוק רישיון חינם למגבלות

חלק מספקי הספריות מספקים רישיונות חלופיים ופחות מגבילים על פי דרישה.

קוד המקור מסופק

ספריית תוכנה עם קופסאות שחורות ממקור סגור עשויה להרגיז. שימוש בקוד מקור יכול להיות נוח יותר מהסיבות הבאות:

  • בעת ניפוי באגים בביצוע קוד יישום, כניסה למקור קוד הספריה יכולה לעזור לך להבין את התנהגות הספריה
  • לקוד המקור יש הערות שימושיות
  • ניתן לשנות את קוד המקור במהירות כדי להתאים לצרכים המיוחדים
  • קוד מקור למופת יכול להיות מעורר השראה

גיל

ספריות נבדקו, ניפוי באגים ותומכות מאז שחרורן הפומבי הראשון. מכיוון שמספר הגרסאות משתנה בין הספריות, אני מבסס את הקריטריון הזה על השנה של המהדורה הציבורית המוקדמת ביותר.

תמיכה ברישומים בספריות

אחזור מידע על קבצים מרוחקים (שם, גודל, תאריך) מהשרת חשוב ברוב היישומים. פרוטוקול FTP מציע את NLSTהפקודה לאחזר את שמות הקבצים בלבד; NLSTפקוד נועדה להיות מנוצלת באופן מפורש על ידי תוכניות. LISTהצעות הפקודה יותר מידע קובץ; כפי שמציין RFC959, "מכיוון שהמידע בקובץ עשוי להשתנות במידה רבה ממערכת למערכת, ייתכן שקשה להשתמש במידע זה באופן אוטומטי בתוכנית, אך עשוי להיות שימושי למדי למשתמש אנושי." שום שיטה סטנדרטית אחרת לא מאחזרת מידע על קבצים; לכן ספריות לקוחות מנסות לנצל את LISTהתגובה. אך זו לא משימה קלה: מכיוון שאין המלצה סמכותית LISTלפורמט התגובה, שרתי FTP אימצו פורמטים שונים:

  • סגנון יוניקס: drwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog
  • סגנון יוניקס חלופי: drwxr-xr-x 1 user01 ftp 512 Jan 29 1997 prog
  • סגנון יוניקס חלופי: 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.

מרבית הספריות תומכות בחיבורים פעילים וגם פסיביים: חיבור פסיבי שימושי כאשר הלקוח עומד מאחורי חומת אש המעכבת חיבורים נכנסים ליציאות גבוהות יותר. RFC1579 דן בפונקציונליות ידידותית לחומת אש זו ביתר פירוט. חלק תיעודי המוצרים מתייחסים קשרים אקטיביים ופסיבי כמו PORTואת PASVפקוד, בהתאמה.

העברה מקבילה

ביישום שולחן עבודה, כאשר העברה מתחילה בשרשור היחיד הראשי, הכל קופא. ספריות מסוימות משרתות באופן אוטומטי את לולאת האירועים לצורך העברות מקבילות בשרשורים נפרדים, כך שלא נצטרך ליצור ולנהל את השרשור שלנו.

תמיכה במפרט JavaBean

ספריות מסוימות מיישמות את מפרט JavaBean. תאימות JavaBean מאפשרת תכנות ויזואלי, המופיע בתכונות Java IDE העיקריות.