1 package org.backsource.utils.io;
2
3
4 import java.io.File;
5 import java.io.IOException;
6 import java.util.Date;
7
8
9 /***
10 * Simple, portable file locking using .lock files.
11 *
12 * <p>WARNING. This lock implementation has several flaws:</p>
13 * <ul>
14 * <li>It goes against the recomendations in the JDK: Note: this method should not be used for file-locking, as the resulting protocol cannot be made to work reliably. The FileLock facility should be used instead.</li>
15 * <li>It is not thread safe when used with the File.list method.</li>
16 * </ul>
17 * <br><br>
18 * <b>Example</b>
19 * <code><pre>
20 * File f = new File("apa");
21 * DotLocl.aquire(f);
22 * // do stuff with f
23 * DotLocl.release(f);
24 * </pre></code>
25 *
26 * @author <a href="mailto:jens.askengren@tim.se">Jens Askengren</a>
27 * @version $Id: DotLock.java,v 1.1.1.1 2004/05/19 12:07:30 pra Exp $
28 */
29 public class DotLock
30 {
31 public static final String LOCK_SUFFIX = ".lock";
32
33 public static final long POLL_TIME = 3000;
34
35
36 /***
37 * Try to aquire the lock for file @param f. Fail emediately if the file is already locked.
38 * @returns true if the lock was aquired.
39 * @throws IOException if the lockfile could not be created
40 */
41 public static boolean tryLock(File f)
42 throws IOException
43 {
44 File lock = getLockFile(f);
45 boolean success = lock.createNewFile();
46 lock.deleteOnExit();
47 return success;
48 }
49
50 /***
51 * Aquire the lock for the file @param f.
52 * If the file is locked, wait until the lock is released.
53 * @throws IOException if the lockfile could not be created
54 * @throws SecurityException if the securitymanager denies write access to the lock file
55 */
56 public static void aquire(File f)
57 throws IOException
58 {
59 File lock = getLockFile(f);
60 while (!lock.createNewFile()) {
61 try {
62 Thread.sleep(POLL_TIME);
63 } catch (InterruptedException e) {
64 throw new IOException ("Could not lock file " + f + ": " + e);
65 }
66 }
67
68 lock.deleteOnExit();
69 }
70
71 /***
72 * Aquire the lock for the file @param f,
73 * wait a most @param timeout milliseconds for the lock to be released.
74 * @returns false if the lock could not be aquired within the timeout.
75 * @throws IOException if the lockfile could not be created
76 * @throws SecurityException if the securitymanager denies write access to the lock file
77 */
78 public static boolean aquire(File f, long timeout)
79 throws IOException
80 {
81 File lock = getLockFile(f);
82 long startTime = (new Date()).getTime();
83
84
85
86
87
88 while (!lock.createNewFile()) {
89
90 long now = (new Date()).getTime();
91 if (now - startTime >= timeout) {
92 return false;
93 }
94
95 try {
96 Thread.sleep(POLL_TIME);
97 } catch (InterruptedException e) {
98 throw new IOException ("Could not lock file " + f + ": " + e);
99 }
100 }
101
102 lock.deleteOnExit();
103 return true;
104 }
105
106
107 /***
108 * Release the lock for file @param f
109 * @returns false if the file was not locked
110 */
111 public static boolean release(File f)
112 {
113 return getLockFile(f).delete();
114 }
115
116 /***
117 * @returns true if the file @param f is locked
118 */
119 public static boolean isLocked(File f)
120 {
121 return getLockFile(f).exists();
122 }
123
124 /***
125 * @returns the lockfile associated with file @param f (no lock will be altered)
126 */
127 public static File getLockFile(File f)
128 {
129 return new File(f + LOCK_SUFFIX);
130 }
131
132 /***
133 * @returns the lockfiles age (in milliseconds) or 0 if the lock does not exists
134 */
135 public static long getLockAge(File f)
136 {
137 File lock = getLockFile(f);
138 long mTime = lock.lastModified();
139 if (mTime == 0L) {
140 return 0L;
141 }
142
143 return ((new Date()).getTime() - mTime);
144 }
145
146
147 }