מדריך WatchService ב- Java NIO2

1. סקירה כללית

במאמר זה, אנו הולכים לחקור את WatchService ממשק ממשקי API של מערכת קבצים של Java NIO.2. זו אחת התכונות הפחות מוכרות של ממשקי ה- API החדשים של IO שהוצגו בג'אווה 7 לצד FileVisitor מִמְשָׁק.

כדי להשתמש ב- WatchService ממשק ביישומים שלך, עליך לייבא את המחלקות המתאימות:

ייבא java.nio.file. *;

2. מדוע להשתמש WatchService

דוגמה נפוצה להבנת מה השירות עושה היא למעשה ה- IDE.

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

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

יישומים אלה משתמשים בתכונה הנקראת הודעת שינוי קבצים זמין בכל מערכות הקבצים.

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

ב- Java 7 NIO.2, ה- WatchService API מספק פתרון מדרגי לניטור ספריות לשינויים. יש לו ממשק API נקי וכל כך מותאם לביצועים שאנחנו לא צריכים ליישם את הפתרון שלנו.

3. איך עובד שירות השעונים?

כדי להשתמש ב- WatchService התכונות, הצעד הראשון הוא ליצור WatchService למשל באמצעות java.nio.file.FileSystems מעמד:

WatchService watchService = FileSystems.getDefault (). NewWatchService ();

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

נתיב נתיב = Paths.get ("pathToDir");

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

WatchKey watchKey = path.register (watchService, StandardWatchEventKinds ...);

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

3.1. ה StandardWatchEventKinds

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

  • StandardWatchEventKinds.ENTRY_CREATE - מופעלת כאשר מתבצעת רשומה חדשה בספריה הצפויה. זה יכול להיות בגלל יצירת קובץ חדש או שינוי שם של קובץ קיים.
  • StandardWatchEventKinds.ENTRY_MODIFY - מופעלת כאשר משתנה רשומה קיימת בספריה הצפויה. כל עריכת הקבצים מפעילה אירוע זה. בפלטפורמות מסוימות, אפילו שינוי תכונות קבצים יפעיל אותו.
  • StandardWatchEventKinds.ENTRY_DELETE - מופעלת כאשר ערך נמחק, מועבר או שונה שם בספריה הנצפית.
  • StandardWatchEventKinds.OVERFLOW - מופעלת כדי לציין אירועים שאבדו או הושלכו. לא נתמקד הרבה בזה

3.2. ה WatchKey

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

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

אנחנו יכולים להשתמש ב- מִשׁאָל ממשק API:

WatchKey watchKey = watchService.poll ();

שיחת API זו חוזרת מיד. הוא מחזיר את מפתח הצפייה הבא בתור שאחד מהאירועים שלו התרחש או בטל אם לא אירעו אירועים רשומים.

אנחנו יכולים גם להשתמש בגרסה עמוסה שלוקחת a פסק זמן טַעֲנָה:

WatchKey watchKey = watchService.poll (זמן פסק זמן, יחידות TimeUnit);

קריאת API זו דומה לזו הקודמת בתמורה. עם זאת, זה חוסם עבור פסק זמן יחידות זמן לתת יותר זמן שבתוכו אירוע עשוי להתרחש במקום להחזיר null באופן מיידי.

לבסוף, אנו יכולים להשתמש ב- לקחת ממשק API:

WatchKey watchKey = watchService.take ();

גישה אחרונה זו פשוט נחסמת עד שמתרחש אירוע.

עלינו לציין משהו חשוב מאוד כאן: כאשר WatchKey מופע מוחזר על ידי אחד מה- מִשׁאָל אוֹ לקחת ממשקי API, זה לא יתפוס אירועים נוספים אם ה- API לא יופעל:

watchKey.reset ();

המשמעות היא שמופע מפתח השעון מוסר מתור שירות השעונים בכל פעם שהוא מוחזר על ידי פעולת סקר. ה אִתחוּל שיחת API מחזירה אותו לתור כדי לחכות לאירועים נוספים.

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

מקש WatchKey; בעוד ((key = watchService.take ())! = null) {עבור (אירוע WatchEvent: key.pollEvents ()) {// process} key.reset (); }

אנו יוצרים מפתח שעון לאחסון ערך ההחזר של פעולת הסקר. לולאת ה- while תיחסם עד שההצהרה המותנית תחזור עם מקש שעון או של null.

כשאנחנו מקבלים מפתח שעון, אז לולאת ה- while מבצעת את הקוד בתוכו. אנו משתמשים ב- WatchKey.pollEvents API להחזרת רשימה של אירועים שהתרחשו. לאחר מכן אנו משתמשים ב- לכל אחד לולאה לעבד אותם אחד אחד.

לאחר עיבוד כל האירועים, עלינו להתקשר אל אִתחוּל ממשק API להצבת מפתח הצפייה שוב.

4. דוגמה לצפייה בספריות

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

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

הקוד מכיל רק כמה שורות קוד ולכן פשוט נשמור אותו בשיטה העיקרית:

מחלקה ציבורית DirectoryWatcher דוגמה {main public public static (String [] args) {WatchService watchService = FileSystems.getDefault (). newWatchService (); נתיב נתיב = Paths.get (System.getProperty ("user.home")); path.register (watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY); מקש WatchKey; בעוד ((key = watchService.take ())! = null) {עבור (אירוע WatchEvent: key.pollEvents ()) {System.out.println ("סוג האירוע:" + event.kind () + ". הקובץ מושפע : "+ event.context () +". "); } key.reset (); }}}

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

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

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

סוג האירוע: ENTRY_CREATE. קובץ מושפע: Document.txt טקסט חדש. סוג האירוע: ENTRY_DELETE. קובץ מושפע: Document.txt חדש. סוג האירוע: ENTRY_CREATE. קובץ מושפע: testFile.txt. סוג האירוע: ENTRY_MODIFY. קובץ מושפע: testFile.txt. סוג האירוע: ENTRY_MODIFY. קובץ מושפע: testFile.txt.

אל תהסס לערוך את הנתיב כדי להצביע על כל ספריה שתרצה לצפות בה.

5. מסקנה

במאמר זה בחנו כמה מהתכונות הפחות נפוצות הזמינות ב- Java 7 NIO.2 - ממשקי API של מערכות קבצים, במיוחד WatchService מִמְשָׁק.

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

וכמו תמיד, קוד המקור המלא לדוגמאות המשמשות במאמר זה זמין בפרויקט Github.