You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2023/06/13 13:59:35 UTC

[commons-io] 02/02: Add FileCleaningTracker.track(Path, Object[, FileDeleteStrategy]).

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git

commit 0671c86b0af8a4e604ad3da465ef1a88576a0fb5
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Tue Jun 13 09:59:28 2023 -0400

    Add FileCleaningTracker.track(Path, Object[, FileDeleteStrategy]).
---
 src/changes/changes.xml                            |   3 +
 .../org/apache/commons/io/FileCleaningTracker.java |  31 ++++++
 .../apache/commons/io/FileCleaningTrackerTest.java | 115 ++++++++++++++++-----
 .../java/org/apache/commons/io/test/TestUtils.java |  18 ++--
 4 files changed, 133 insertions(+), 34 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ad806944..ec5c285d 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -52,6 +52,9 @@ The <action> type attribute can be add,update,fix,remove.
       <action dev="ggregory" type="add" due-to="Gary Gregory">
         Add DeferredFileOutputStream.getPath().
       </action>
+      <action dev="ggregory" type="add" due-to="Gary Gregory">
+        Add FileCleaningTracker.track(Path, Object[, FileDeleteStrategy]).
+      </action>
       <!-- FIX -->
       <action dev="ggregory" type="fix" issue="IO-799" due-to="Jeroen van der Vegt, Gary Gregory">
         ReaderInputStream.read() throws an exception instead of returning -1 when called again after returning -1.
diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java
index 95363645..98c33b0d 100644
--- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java
+++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java
@@ -19,6 +19,7 @@ package org.apache.commons.io;
 import java.io.File;
 import java.lang.ref.PhantomReference;
 import java.lang.ref.ReferenceQueue;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -255,6 +256,36 @@ public class FileCleaningTracker {
         addTracker(file.getPath(), marker, deleteStrategy);
     }
 
+    /**
+     * Tracks the specified file, using the provided marker, deleting the file
+     * when the marker instance is garbage collected.
+     * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
+     *
+     * @param file  the file to be tracked, not null
+     * @param marker  the marker object used to track the file, not null
+     * @throws NullPointerException if the file is null
+     * @since 2.14.0
+     */
+    public void track(final Path file, final Object marker) {
+        track(file, marker, null);
+    }
+
+    /**
+     * Tracks the specified file, using the provided marker, deleting the file
+     * when the marker instance is garbage collected.
+     * The specified deletion strategy is used.
+     *
+     * @param file  the file to be tracked, not null
+     * @param marker  the marker object used to track the file, not null
+     * @param deleteStrategy  the strategy to delete the file, null means normal
+     * @throws NullPointerException if the file is null
+     * @since 2.14.0
+     */
+    public void track(final Path file, final Object marker, final FileDeleteStrategy deleteStrategy) {
+        Objects.requireNonNull(file, "file");
+        addTracker(file.toAbsolutePath().toString(), marker, deleteStrategy);
+    }
+
     /**
      * Tracks the specified file, using the provided marker, deleting the file
      * when the marker instance is garbage collected.
diff --git a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java
index bb47ae23..01c9d35d 100644
--- a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java
+++ b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java
@@ -29,6 +29,8 @@ import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.lang.ref.ReferenceQueue;
 import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -44,6 +46,7 @@ import org.junit.jupiter.api.Test;
 public class FileCleaningTrackerTest extends AbstractTempDirTest {
 
     private File testFile;
+    private Path testPath;
 
     private FileCleaningTracker theInstance;
 
@@ -63,9 +66,18 @@ public class FileCleaningTrackerTest extends AbstractTempDirTest {
         }
     }
 
+    private void pauseForDeleteToComplete(Path file) {
+        int count = 0;
+        while (Files.exists(file) && count++ < 40) {
+            TestUtils.sleepQuietly(500L);
+            file = Paths.get(file.toAbsolutePath().toString());
+        }
+    }
+
     @BeforeEach
     public void setUp() {
         testFile = new File(tempDirFile, "file-test.txt");
+        testPath = testFile.toPath();
         theInstance = newInstance();
     }
 
@@ -100,51 +112,59 @@ public class FileCleaningTrackerTest extends AbstractTempDirTest {
     }
 
     @Test
-    public void testFileCleanerDirectory() throws Exception {
-        TestUtils.createFile(testFile, 100);
+    public void testFileCleanerDirectory_ForceStrategy_FileSource() throws Exception {
+        if (!testFile.getParentFile().exists()) {
+            throw new IOException("Cannot create file " + testFile
+                    + " as the parent directory does not exist");
+        }
+        try (BufferedOutputStream output =
+                new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
+            TestUtils.generateTestData(output, 100);
+        }
         assertTrue(testFile.exists());
         assertTrue(tempDirFile.exists());
 
         Object obj = new Object();
         assertEquals(0, theInstance.getTrackCount());
-        theInstance.track(tempDirFile, obj);
+        theInstance.track(tempDirFile, obj, FileDeleteStrategy.FORCE);
         assertEquals(1, theInstance.getTrackCount());
 
         obj = null;
 
         waitUntilTrackCount();
+        pauseForDeleteToComplete(testFile.getParentFile());
 
         assertEquals(0, theInstance.getTrackCount());
-        assertTrue(testFile.exists());  // not deleted, as dir not empty
-        assertTrue(testFile.getParentFile().exists());  // not deleted, as dir not empty
+        assertFalse(new File(testFile.getPath()).exists(), showFailures());
+        assertFalse(testFile.getParentFile().exists(), showFailures());
     }
 
     @Test
-    public void testFileCleanerDirectory_ForceStrategy() throws Exception {
-        if (!testFile.getParentFile().exists()) {
-            throw new IOException("Cannot create file " + testFile
+    public void testFileCleanerDirectory_ForceStrategy_PathSource() throws Exception {
+        if (!Files.exists(testPath.getParent())) {
+            throw new IOException("Cannot create file " + testPath
                     + " as the parent directory does not exist");
         }
         try (BufferedOutputStream output =
-                new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
+                new BufferedOutputStream(Files.newOutputStream(testPath))) {
             TestUtils.generateTestData(output, 100);
         }
-        assertTrue(testFile.exists());
-        assertTrue(tempDirFile.exists());
+        assertTrue(Files.exists(testPath));
+        assertTrue(Files.exists(tempDirPath));
 
         Object obj = new Object();
         assertEquals(0, theInstance.getTrackCount());
-        theInstance.track(tempDirFile, obj, FileDeleteStrategy.FORCE);
+        theInstance.track(tempDirPath, obj, FileDeleteStrategy.FORCE);
         assertEquals(1, theInstance.getTrackCount());
 
         obj = null;
 
         waitUntilTrackCount();
-        pauseForDeleteToComplete(testFile.getParentFile());
+        pauseForDeleteToComplete(testPath.getParent());
 
         assertEquals(0, theInstance.getTrackCount());
-        assertFalse(new File(testFile.getPath()).exists(), showFailures());
-        assertFalse(testFile.getParentFile().exists(), showFailures());
+        assertFalse(Files.exists(testPath), showFailures());
+        assertFalse(Files.exists(testPath.getParent()), showFailures());
     }
 
     @Test
@@ -167,6 +187,46 @@ public class FileCleaningTrackerTest extends AbstractTempDirTest {
         assertTrue(testFile.getParentFile().exists());  // not deleted, as dir not empty
     }
 
+    @Test
+    public void testFileCleanerDirectoryFileSource() throws Exception {
+        TestUtils.createFile(testFile, 100);
+        assertTrue(testFile.exists());
+        assertTrue(tempDirFile.exists());
+
+        Object obj = new Object();
+        assertEquals(0, theInstance.getTrackCount());
+        theInstance.track(tempDirFile, obj);
+        assertEquals(1, theInstance.getTrackCount());
+
+        obj = null;
+
+        waitUntilTrackCount();
+
+        assertEquals(0, theInstance.getTrackCount());
+        assertTrue(testFile.exists());  // not deleted, as dir not empty
+        assertTrue(testFile.getParentFile().exists());  // not deleted, as dir not empty
+    }
+
+    @Test
+    public void testFileCleanerDirectoryPathSource() throws Exception {
+        TestUtils.createFile(testPath, 100);
+        assertTrue(Files.exists(testPath));
+        assertTrue(Files.exists(tempDirPath));
+
+        Object obj = new Object();
+        assertEquals(0, theInstance.getTrackCount());
+        theInstance.track(tempDirPath, obj);
+        assertEquals(1, theInstance.getTrackCount());
+
+        obj = null;
+
+        waitUntilTrackCount();
+
+        assertEquals(0, theInstance.getTrackCount());
+        assertTrue(Files.exists(testPath));  // not deleted, as dir not empty
+        assertTrue(Files.exists(testPath.getParent()));  // not deleted, as dir not empty
+    }
+
     @Test
     public void testFileCleanerExitWhenFinished_NoTrackAfter() {
         assertFalse(theInstance.exitWhenFinished);
@@ -187,23 +247,22 @@ public class FileCleaningTrackerTest extends AbstractTempDirTest {
         final String path = testFile.getPath();
 
         assertFalse(testFile.exists(), "1-testFile exists: " + testFile);
-        RandomAccessFile r = createRandomAccessFile();
-        assertTrue(testFile.exists(), "2-testFile exists");
+        try (RandomAccessFile raf = createRandomAccessFile()) {
+            assertTrue(testFile.exists(), "2-testFile exists");
 
-        assertEquals(0, theInstance.getTrackCount(), "3-Track Count");
-        theInstance.track(path, r);
-        assertEquals(1, theInstance.getTrackCount(), "4-Track Count");
-        assertFalse(theInstance.exitWhenFinished, "5-exitWhenFinished");
-        assertTrue(theInstance.reaper.isAlive(), "6-reaper.isAlive");
+            assertEquals(0, theInstance.getTrackCount(), "3-Track Count");
+            theInstance.track(path, raf);
+            assertEquals(1, theInstance.getTrackCount(), "4-Track Count");
+            assertFalse(theInstance.exitWhenFinished, "5-exitWhenFinished");
+            assertTrue(theInstance.reaper.isAlive(), "6-reaper.isAlive");
 
-        assertFalse(theInstance.exitWhenFinished, "7-exitWhenFinished");
-        theInstance.exitWhenFinished();
-        assertTrue(theInstance.exitWhenFinished, "8-exitWhenFinished");
-        assertTrue(theInstance.reaper.isAlive(), "9-reaper.isAlive");
+            assertFalse(theInstance.exitWhenFinished, "7-exitWhenFinished");
+            theInstance.exitWhenFinished();
+            assertTrue(theInstance.exitWhenFinished, "8-exitWhenFinished");
+            assertTrue(theInstance.reaper.isAlive(), "9-reaper.isAlive");
 
-        r.close();
+        }
         testFile = null;
-        r = null;
 
         waitUntilTrackCount();
         pauseForDeleteToComplete(new File(path));
diff --git a/src/test/java/org/apache/commons/io/test/TestUtils.java b/src/test/java/org/apache/commons/io/test/TestUtils.java
index 8ace275e..cc9d7ff8 100644
--- a/src/test/java/org/apache/commons/io/test/TestUtils.java
+++ b/src/test/java/org/apache/commons/io/test/TestUtils.java
@@ -164,14 +164,20 @@ public abstract class TestUtils {
         }
     }
 
-    public static void createFile(final File file, final long size)
-            throws IOException {
+    public static void createFile(final File file, final long size) throws IOException {
         if (!file.getParentFile().exists()) {
-            throw new IOException("Cannot create file " + file
-                    + " as the parent directory does not exist");
+            throw new IOException("Cannot create file " + file + " as the parent directory does not exist");
+        }
+        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
+            generateTestData(output, size);
+        }
+    }
+
+    public static void createFile(final Path file, final long size) throws IOException {
+        if (!Files.exists(file.getParent())) {
+            throw new IOException("Cannot create file " + file + " as the parent directory does not exist");
         }
-        try (BufferedOutputStream output =
-                new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
+        try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file))) {
             generateTestData(output, size);
         }
     }