מחק ספריה רקורסיבית בג'אווה

1. הקדמה

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

2. מחיקת מדריך רקורסיבי

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

  1. קבל את כל תוכן הספרייה למחיקה
  2. מחק את כל הילדים שאינם ספריה (יציאה מ- recursion)
  3. עבור כל ספריה משנה של הספריה הנוכחית, התחל משלב 1 (שלב רקורסיבי)
  4. מחק את הספרייה

בואו נשתמש באלגוריתם הפשוט הזה:

deleteDirectory בוליאני (directoryToBeDeleted File) {File [] allContents = directoryToBeDeleted.listFiles (); אם (allContents! = null) {עבור (קובץ קובץ: allContents) {deleteDirectory (קובץ); }} להחזיר directoryToBeDeleted.delete (); }

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

@Test הציבור בטל givenDirectory_whenDeletedWithRecursion_thenIsGone () זורק IOException {נתיב pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); תוצאה בוליאנית = deleteDirectory (pathToBeDeleted.toFile ()); assertTrue (תוצאה); assertFalse ("הספריה עדיין קיימת", Files.exists (pathToBeDeleted)); }

ה @לפני שיטת מחלקת הבדיקה שלנו יוצרת עץ ספריות עם ספריות משנה וקבצים ב pathToBeDeleted מיקום ו @לאחר השיטה מנקה את הספרייה במידת הצורך.

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

3. שימוש FileUtils מ commons-io

ראשית, עלינו להוסיף את commons-io תלות בפרויקט Maven:

 commons-io commons-io 2.5 

הגרסה האחרונה של התלות נמצאת כאן.

עכשיו, אנחנו יכולים להשתמש FileUtils לביצוע פעולות מבוססות קבצים כולל deleteDirectory () עם הצהרה אחת בלבד:

FileUtils.deleteDirectory (קובץ);

4. שימוש FileSystemUtils מאביב

לחלופין, אנו יכולים להוסיף את ה- sפרינג-ליבה תלות בפרויקט Maven:

 org.springframework spring-core 4.3.10.RELEASE 

הגרסה האחרונה של התלות נמצאת כאן.

אנחנו יכולים להשתמש ב- deleteRecursively () שיטה ב FileSystemUtils לביצוע המחיקה:

תוצאה בוליאנית = FileSystemUtils.deleteRecursively (קובץ);

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

5. שימוש ב- NIO2 עם Java 7

Java 7 הציגה דרך חדשה לגמרי לביצוע פעולות קבצים באמצעות קבצים. זה מאפשר לנו לחצות עץ מדריך ולהשתמש בקריאות חוזרות לצורך פעולות שיבוצעו.

חלל ציבורי כאשרDeletedWithNIO2WalkFileTree_thenIsGone () זורק IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walkFileTree (pathToBeDeleted, חדש SimpleFileVisitor () {@Override פומבי FileVisitResult postVisitDirectory (נתיב dir, IOException exc) זורק IOException {Files.delete (dir); להחזיר FileVisitResult.CONTINUE;} @Override תוצאות קובץ FileFit ) זורק את IOException {Files.delete (file); להחזיר FileVisitResult.CONTINUE;}}); assertFalse ("הספריה עדיין קיימת", Files.exists (pathToBeDeleted)); }

ה Files.walkFileTree () השיטה חוצה עץ קבצים ופולטת אירועים. עלינו לציין התקשרות חוזרות לאירועים אלה. אז, במקרה זה, נגדיר SimpleFileVisitor לנקוט בפעולות הבאות לאירועים שנוצרו:

  1. ביקור בקובץ - מחק אותו
  2. ביקור בספריה לפני עיבוד הערכים שלה - אל תעשה כלום
  3. ביקור בספריה לאחר עיבוד הערכים שלה - מחק את הספרייה, מכיוון שכל הערכים בספריה זו היו מעובדים (או נמחקים) עד עכשיו
  4. לא ניתן לבקר בקובץ - לסדר מחדש IOException שגרם לכישלון

עיין במבוא ל- API של Java NIO2 File לקבלת פרטים נוספים על NIO2 APIs על טיפול בפעולות קבצים.

6. שימוש NIO2 עם Java 8

מאז Java 8, Stream API מציע דרך טובה עוד יותר למחיקת ספריה:

@Test הציבור בטל כאשרDeletedWithFilesWalk_thenIsGone () זורק IOException {Path pathToBeDeleted = TEMP_DIRECTORY.resolve (DIRECTORY_NAME); Files.walk (pathToBeDeleted) .sorted (Comparator.reverseOrder ()) .map (Path :: toFile) .forEach (File :: delete); assertFalse ("הספריה עדיין קיימת", Files.exists (pathToBeDeleted)); }

פה, Files.walk () מחזירה א זרם שֶׁל נָתִיב שאנחנו ממיינים בסדר הפוך. זה מציב את הנתיבים המציינים את תוכן הספריות לפני ספריות עצמן. לאחר מכן הוא ממפה נָתִיב ל קוֹבֶץ ומוחק כל אחד קוֹבֶץ.

7. מסקנה

במדריך מהיר זה בדקנו דרכים שונות למחיקת ספריה. בעוד שראינו כיצד להשתמש ברקורסיה למחיקה, בדקנו גם כמה ספריות, NIO2 ממנף אירועים ו- Java 8 Path Stream תוך שימוש בפרדיגמת תכנות פונקציונלית.

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