Skip to content

Commit 0671c86

Browse files
committed
Add FileCleaningTracker.track(Path, Object[, FileDeleteStrategy]).
1 parent 32d2f33 commit 0671c86

4 files changed

Lines changed: 133 additions & 34 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ The <action> type attribute can be add,update,fix,remove.
5252
<action dev="ggregory" type="add" due-to="Gary Gregory">
5353
Add DeferredFileOutputStream.getPath().
5454
</action>
55+
<action dev="ggregory" type="add" due-to="Gary Gregory">
56+
Add FileCleaningTracker.track(Path, Object[, FileDeleteStrategy]).
57+
</action>
5558
<!-- FIX -->
5659
<action dev="ggregory" type="fix" issue="IO-799" due-to="Jeroen van der Vegt, Gary Gregory">
5760
ReaderInputStream.read() throws an exception instead of returning -1 when called again after returning -1.

src/main/java/org/apache/commons/io/FileCleaningTracker.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.File;
2020
import java.lang.ref.PhantomReference;
2121
import java.lang.ref.ReferenceQueue;
22+
import java.nio.file.Path;
2223
import java.util.ArrayList;
2324
import java.util.Collection;
2425
import java.util.Collections;
@@ -255,6 +256,36 @@ public void track(final File file, final Object marker, final FileDeleteStrategy
255256
addTracker(file.getPath(), marker, deleteStrategy);
256257
}
257258

259+
/**
260+
* Tracks the specified file, using the provided marker, deleting the file
261+
* when the marker instance is garbage collected.
262+
* The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
263+
*
264+
* @param file the file to be tracked, not null
265+
* @param marker the marker object used to track the file, not null
266+
* @throws NullPointerException if the file is null
267+
* @since 2.14.0
268+
*/
269+
public void track(final Path file, final Object marker) {
270+
track(file, marker, null);
271+
}
272+
273+
/**
274+
* Tracks the specified file, using the provided marker, deleting the file
275+
* when the marker instance is garbage collected.
276+
* The specified deletion strategy is used.
277+
*
278+
* @param file the file to be tracked, not null
279+
* @param marker the marker object used to track the file, not null
280+
* @param deleteStrategy the strategy to delete the file, null means normal
281+
* @throws NullPointerException if the file is null
282+
* @since 2.14.0
283+
*/
284+
public void track(final Path file, final Object marker, final FileDeleteStrategy deleteStrategy) {
285+
Objects.requireNonNull(file, "file");
286+
addTracker(file.toAbsolutePath().toString(), marker, deleteStrategy);
287+
}
288+
258289
/**
259290
* Tracks the specified file, using the provided marker, deleting the file
260291
* when the marker instance is garbage collected.

src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java

Lines changed: 87 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import java.io.RandomAccessFile;
3030
import java.lang.ref.ReferenceQueue;
3131
import java.nio.file.Files;
32+
import java.nio.file.Path;
33+
import java.nio.file.Paths;
3234
import java.util.ArrayList;
3335
import java.util.List;
3436

@@ -44,6 +46,7 @@
4446
public class FileCleaningTrackerTest extends AbstractTempDirTest {
4547

4648
private File testFile;
49+
private Path testPath;
4750

4851
private FileCleaningTracker theInstance;
4952

@@ -63,9 +66,18 @@ private void pauseForDeleteToComplete(File file) {
6366
}
6467
}
6568

69+
private void pauseForDeleteToComplete(Path file) {
70+
int count = 0;
71+
while (Files.exists(file) && count++ < 40) {
72+
TestUtils.sleepQuietly(500L);
73+
file = Paths.get(file.toAbsolutePath().toString());
74+
}
75+
}
76+
6677
@BeforeEach
6778
public void setUp() {
6879
testFile = new File(tempDirFile, "file-test.txt");
80+
testPath = testFile.toPath();
6981
theInstance = newInstance();
7082
}
7183

@@ -100,51 +112,59 @@ public void tearDown() {
100112
}
101113

102114
@Test
103-
public void testFileCleanerDirectory() throws Exception {
104-
TestUtils.createFile(testFile, 100);
115+
public void testFileCleanerDirectory_ForceStrategy_FileSource() throws Exception {
116+
if (!testFile.getParentFile().exists()) {
117+
throw new IOException("Cannot create file " + testFile
118+
+ " as the parent directory does not exist");
119+
}
120+
try (BufferedOutputStream output =
121+
new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
122+
TestUtils.generateTestData(output, 100);
123+
}
105124
assertTrue(testFile.exists());
106125
assertTrue(tempDirFile.exists());
107126

108127
Object obj = new Object();
109128
assertEquals(0, theInstance.getTrackCount());
110-
theInstance.track(tempDirFile, obj);
129+
theInstance.track(tempDirFile, obj, FileDeleteStrategy.FORCE);
111130
assertEquals(1, theInstance.getTrackCount());
112131

113132
obj = null;
114133

115134
waitUntilTrackCount();
135+
pauseForDeleteToComplete(testFile.getParentFile());
116136

117137
assertEquals(0, theInstance.getTrackCount());
118-
assertTrue(testFile.exists()); // not deleted, as dir not empty
119-
assertTrue(testFile.getParentFile().exists()); // not deleted, as dir not empty
138+
assertFalse(new File(testFile.getPath()).exists(), showFailures());
139+
assertFalse(testFile.getParentFile().exists(), showFailures());
120140
}
121141

122142
@Test
123-
public void testFileCleanerDirectory_ForceStrategy() throws Exception {
124-
if (!testFile.getParentFile().exists()) {
125-
throw new IOException("Cannot create file " + testFile
143+
public void testFileCleanerDirectory_ForceStrategy_PathSource() throws Exception {
144+
if (!Files.exists(testPath.getParent())) {
145+
throw new IOException("Cannot create file " + testPath
126146
+ " as the parent directory does not exist");
127147
}
128148
try (BufferedOutputStream output =
129-
new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
149+
new BufferedOutputStream(Files.newOutputStream(testPath))) {
130150
TestUtils.generateTestData(output, 100);
131151
}
132-
assertTrue(testFile.exists());
133-
assertTrue(tempDirFile.exists());
152+
assertTrue(Files.exists(testPath));
153+
assertTrue(Files.exists(tempDirPath));
134154

135155
Object obj = new Object();
136156
assertEquals(0, theInstance.getTrackCount());
137-
theInstance.track(tempDirFile, obj, FileDeleteStrategy.FORCE);
157+
theInstance.track(tempDirPath, obj, FileDeleteStrategy.FORCE);
138158
assertEquals(1, theInstance.getTrackCount());
139159

140160
obj = null;
141161

142162
waitUntilTrackCount();
143-
pauseForDeleteToComplete(testFile.getParentFile());
163+
pauseForDeleteToComplete(testPath.getParent());
144164

145165
assertEquals(0, theInstance.getTrackCount());
146-
assertFalse(new File(testFile.getPath()).exists(), showFailures());
147-
assertFalse(testFile.getParentFile().exists(), showFailures());
166+
assertFalse(Files.exists(testPath), showFailures());
167+
assertFalse(Files.exists(testPath.getParent()), showFailures());
148168
}
149169

150170
@Test
@@ -167,6 +187,46 @@ public void testFileCleanerDirectory_NullStrategy() throws Exception {
167187
assertTrue(testFile.getParentFile().exists()); // not deleted, as dir not empty
168188
}
169189

190+
@Test
191+
public void testFileCleanerDirectoryFileSource() throws Exception {
192+
TestUtils.createFile(testFile, 100);
193+
assertTrue(testFile.exists());
194+
assertTrue(tempDirFile.exists());
195+
196+
Object obj = new Object();
197+
assertEquals(0, theInstance.getTrackCount());
198+
theInstance.track(tempDirFile, obj);
199+
assertEquals(1, theInstance.getTrackCount());
200+
201+
obj = null;
202+
203+
waitUntilTrackCount();
204+
205+
assertEquals(0, theInstance.getTrackCount());
206+
assertTrue(testFile.exists()); // not deleted, as dir not empty
207+
assertTrue(testFile.getParentFile().exists()); // not deleted, as dir not empty
208+
}
209+
210+
@Test
211+
public void testFileCleanerDirectoryPathSource() throws Exception {
212+
TestUtils.createFile(testPath, 100);
213+
assertTrue(Files.exists(testPath));
214+
assertTrue(Files.exists(tempDirPath));
215+
216+
Object obj = new Object();
217+
assertEquals(0, theInstance.getTrackCount());
218+
theInstance.track(tempDirPath, obj);
219+
assertEquals(1, theInstance.getTrackCount());
220+
221+
obj = null;
222+
223+
waitUntilTrackCount();
224+
225+
assertEquals(0, theInstance.getTrackCount());
226+
assertTrue(Files.exists(testPath)); // not deleted, as dir not empty
227+
assertTrue(Files.exists(testPath.getParent())); // not deleted, as dir not empty
228+
}
229+
170230
@Test
171231
public void testFileCleanerExitWhenFinished_NoTrackAfter() {
172232
assertFalse(theInstance.exitWhenFinished);
@@ -187,23 +247,22 @@ public void testFileCleanerExitWhenFinished1() throws Exception {
187247
final String path = testFile.getPath();
188248

189249
assertFalse(testFile.exists(), "1-testFile exists: " + testFile);
190-
RandomAccessFile r = createRandomAccessFile();
191-
assertTrue(testFile.exists(), "2-testFile exists");
250+
try (RandomAccessFile raf = createRandomAccessFile()) {
251+
assertTrue(testFile.exists(), "2-testFile exists");
192252

193-
assertEquals(0, theInstance.getTrackCount(), "3-Track Count");
194-
theInstance.track(path, r);
195-
assertEquals(1, theInstance.getTrackCount(), "4-Track Count");
196-
assertFalse(theInstance.exitWhenFinished, "5-exitWhenFinished");
197-
assertTrue(theInstance.reaper.isAlive(), "6-reaper.isAlive");
253+
assertEquals(0, theInstance.getTrackCount(), "3-Track Count");
254+
theInstance.track(path, raf);
255+
assertEquals(1, theInstance.getTrackCount(), "4-Track Count");
256+
assertFalse(theInstance.exitWhenFinished, "5-exitWhenFinished");
257+
assertTrue(theInstance.reaper.isAlive(), "6-reaper.isAlive");
198258

199-
assertFalse(theInstance.exitWhenFinished, "7-exitWhenFinished");
200-
theInstance.exitWhenFinished();
201-
assertTrue(theInstance.exitWhenFinished, "8-exitWhenFinished");
202-
assertTrue(theInstance.reaper.isAlive(), "9-reaper.isAlive");
259+
assertFalse(theInstance.exitWhenFinished, "7-exitWhenFinished");
260+
theInstance.exitWhenFinished();
261+
assertTrue(theInstance.exitWhenFinished, "8-exitWhenFinished");
262+
assertTrue(theInstance.reaper.isAlive(), "9-reaper.isAlive");
203263

204-
r.close();
264+
}
205265
testFile = null;
206-
r = null;
207266

208267
waitUntilTrackCount();
209268
pauseForDeleteToComplete(new File(path));

src/test/java/org/apache/commons/io/test/TestUtils.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,20 @@ public static void checkWrite(final Writer output) {
164164
}
165165
}
166166

167-
public static void createFile(final File file, final long size)
168-
throws IOException {
167+
public static void createFile(final File file, final long size) throws IOException {
169168
if (!file.getParentFile().exists()) {
170-
throw new IOException("Cannot create file " + file
171-
+ " as the parent directory does not exist");
169+
throw new IOException("Cannot create file " + file + " as the parent directory does not exist");
170+
}
171+
try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
172+
generateTestData(output, size);
173+
}
174+
}
175+
176+
public static void createFile(final Path file, final long size) throws IOException {
177+
if (!Files.exists(file.getParent())) {
178+
throw new IOException("Cannot create file " + file + " as the parent directory does not exist");
172179
}
173-
try (BufferedOutputStream output =
174-
new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
180+
try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file))) {
175181
generateTestData(output, size);
176182
}
177183
}

0 commit comments

Comments
 (0)