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. import java.io.File;
  18. import java.lang.ref.PhantomReference;
  19. import java.lang.ref.ReferenceQueue;
  20. import java.util.Collection;
  21. import java.util.Vector;
  22. /**
  23. * Keeps track of files awaiting deletion, and deletes them when an associated
  24. * marker object is reclaimed by the garbage collector.
  25. *
  26. * @author Noel Bergman
  27. * @author Martin Cooper
  28. *
  29. * @version $Id: FileCleaner.java,v 1.1 2004/03/18 06:04:14 martinc Exp $
  30. */
  31. public class FileCleaner {
  32. /**
  33. * Queue of <code>Tracker</code> instances being watched.
  34. */
  35. private static ReferenceQueue /* Tracker */ q = new ReferenceQueue();
  36. /**
  37. * Collection of <code>Tracker</code> instances in existence.
  38. */
  39. private static Collection /* Tracker */ trackers = new Vector();
  40. /**
  41. * The thread that will clean up registered files.
  42. */
  43. private static Thread reaper = new Thread("File Reaper") {
  44. /**
  45. * Run the reaper thread that will delete files as their associated
  46. * marker objects are reclaimed by the garbage collector.
  47. */
  48. public void run() {
  49. for (;;) {
  50. Tracker tracker = null;
  51. try {
  52. // Wait for a tracker to remove.
  53. tracker = (Tracker) q.remove();
  54. } catch(Exception _) {
  55. continue;
  56. }
  57. tracker.delete();
  58. tracker.clear();
  59. trackers.remove(tracker);
  60. }
  61. }
  62. };
  63. /**
  64. * The static initializer that starts the reaper thread.
  65. */
  66. static {
  67. reaper.setPriority(Thread.MAX_PRIORITY);
  68. reaper.setDaemon(true);
  69. reaper.start();
  70. }
  71. /**
  72. * Track the specified file, using the provided marker, deleting the file
  73. * when the marker instance is garbage collected.
  74. *
  75. * @param file The file to be tracked.
  76. * @param marker The marker object used to track the file.
  77. */
  78. public static void track(File file, Object marker) {
  79. trackers.add(new Tracker(file, marker, q));
  80. }
  81. /**
  82. * Track the specified file, using the provided marker, deleting the file
  83. * when the marker instance is garbage collected.
  84. *
  85. * @param path The full path to the file to be tracked.
  86. * @param marker The marker object used to track the file.
  87. */
  88. public static void track(String path, Object marker) {
  89. trackers.add(new Tracker(path, marker, q));
  90. }
  91. /**
  92. * Retrieve the number of files currently being tracked, and therefore
  93. * awaiting deletion.
  94. *
  95. * @return the number of files being tracked.
  96. */
  97. public static int getTrackCount() {
  98. return trackers.size();
  99. }
  100. /**
  101. * Inner class which acts as the reference for a file pending deletion.
  102. */
  103. private static class Tracker extends PhantomReference {
  104. /**
  105. * The full path to the file being tracked.
  106. */
  107. private String path;
  108. /**
  109. * Constructs an instance of this class from the supplied parameters.
  110. *
  111. * @param file The file to be tracked.
  112. * @param marker The marker object used to track the file.
  113. * @param q The queue on to which the tracker will be pushed.
  114. */
  115. public Tracker(File file, Object marker, ReferenceQueue q) {
  116. this(file.getPath(), marker, q);
  117. }
  118. /**
  119. * Constructs an instance of this class from the supplied parameters.
  120. *
  121. * @param path The full path to the file to be tracked.
  122. * @param marker The marker object used to track the file.
  123. * @param q The queue on to which the tracker will be pushed.
  124. */
  125. public Tracker(String path, Object marker, ReferenceQueue q) {
  126. super(marker, q);
  127. this.path = path;
  128. }
  129. /**
  130. * Deletes the file associated with this tracker instance.
  131. *
  132. * @return <code>true</code> if the file was deleted successfully;
  133. * <code>false</code> otherwise.
  134. */
  135. public boolean delete() {
  136. return new File(path).delete();
  137. }
  138. }
  139. }