1+ /*
2+ * Copyright 2001-2004 The Apache Software Foundation.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+ package org .apache .commons .io ;
17+
18+ import java .io .File ;
19+ import java .lang .ref .PhantomReference ;
20+ import java .lang .ref .ReferenceQueue ;
21+ import java .util .Collection ;
22+ import java .util .Vector ;
23+
24+ /**
25+ * Keeps track of files awaiting deletion, and deletes them when an associated
26+ * marker object is reclaimed by the garbage collector.
27+ *
28+ * @author Noel Bergman
29+ * @author Martin Cooper
30+ *
31+ * @version $Id: FileCleaner.java,v 1.1 2004/03/18 06:04:14 martinc Exp $
32+ */
33+ public class FileCleaner {
34+
35+ /**
36+ * Queue of <code>Tracker</code> instances being watched.
37+ */
38+ private static ReferenceQueue /* Tracker */ q = new ReferenceQueue ();
39+
40+ /**
41+ * Collection of <code>Tracker</code> instances in existence.
42+ */
43+ private static Collection /* Tracker */ trackers = new Vector ();
44+
45+ /**
46+ * The thread that will clean up registered files.
47+ */
48+ private static Thread reaper = new Thread ("File Reaper" ) {
49+
50+ /**
51+ * Run the reaper thread that will delete files as their associated
52+ * marker objects are reclaimed by the garbage collector.
53+ */
54+ public void run () {
55+ for (;;) {
56+ Tracker tracker = null ;
57+ try {
58+ // Wait for a tracker to remove.
59+ tracker = (Tracker ) q .remove ();
60+ } catch (Exception _) {
61+ continue ;
62+ }
63+
64+ tracker .delete ();
65+ tracker .clear ();
66+ trackers .remove (tracker );
67+ }
68+ }
69+ };
70+
71+ /**
72+ * The static initializer that starts the reaper thread.
73+ */
74+ static {
75+ reaper .setPriority (Thread .MAX_PRIORITY );
76+ reaper .setDaemon (true );
77+ reaper .start ();
78+ }
79+
80+ /**
81+ * Track the specified file, using the provided marker, deleting the file
82+ * when the marker instance is garbage collected.
83+ *
84+ * @param file The file to be tracked.
85+ * @param marker The marker object used to track the file.
86+ */
87+ public static void track (File file , Object marker ) {
88+ trackers .add (new Tracker (file , marker , q ));
89+ }
90+
91+ /**
92+ * Track the specified file, using the provided marker, deleting the file
93+ * when the marker instance is garbage collected.
94+ *
95+ * @param path The full path to the file to be tracked.
96+ * @param marker The marker object used to track the file.
97+ */
98+ public static void track (String path , Object marker ) {
99+ trackers .add (new Tracker (path , marker , q ));
100+ }
101+
102+ /**
103+ * Retrieve the number of files currently being tracked, and therefore
104+ * awaiting deletion.
105+ *
106+ * @return the number of files being tracked.
107+ */
108+ public static int getTrackCount () {
109+ return trackers .size ();
110+ }
111+
112+ /**
113+ * Inner class which acts as the reference for a file pending deletion.
114+ */
115+ private static class Tracker extends PhantomReference {
116+
117+ /**
118+ * The full path to the file being tracked.
119+ */
120+ private String path ;
121+
122+ /**
123+ * Constructs an instance of this class from the supplied parameters.
124+ *
125+ * @param file The file to be tracked.
126+ * @param marker The marker object used to track the file.
127+ * @param q The queue on to which the tracker will be pushed.
128+ */
129+ public Tracker (File file , Object marker , ReferenceQueue q ) {
130+ this (file .getPath (), marker , q );
131+ }
132+
133+ /**
134+ * Constructs an instance of this class from the supplied parameters.
135+ *
136+ * @param path The full path to the file to be tracked.
137+ * @param marker The marker object used to track the file.
138+ * @param q The queue on to which the tracker will be pushed.
139+ */
140+ public Tracker (String path , Object marker , ReferenceQueue q ) {
141+ super (marker , q );
142+ this .path = path ;
143+ }
144+
145+ /**
146+ * Deletes the file associated with this tracker instance.
147+ *
148+ * @return <code>true</code> if the file was deleted successfully;
149+ * <code>false</code> otherwise.
150+ */
151+ public boolean delete () {
152+ return new File (path ).delete ();
153+ }
154+ }
155+ }
0 commit comments