2 * This file is part of the Vamsas Client version 0.2.
\r
3 * Copyright 2010 by Jim Procter, Iain Milne, Pierre Marguerite,
\r
4 * Andrew Waterhouse and Dominik Lindner.
\r
6 * Earlier versions have also been incorporated into Jalview version 2.4
\r
7 * since 2008, and TOPALi version 2 since 2007.
\r
9 * The Vamsas Client is free software: you can redistribute it and/or modify
\r
10 * it under the terms of the GNU Lesser General Public License as published by
\r
11 * the Free Software Foundation, either version 3 of the License, or
\r
12 * (at your option) any later version.
\r
14 * The Vamsas Client is distributed in the hope that it will be useful,
\r
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 * GNU Lesser General Public License for more details.
\r
19 * You should have received a copy of the GNU Lesser General Public License
\r
20 * along with the Vamsas Client. If not, see <http://www.gnu.org/licenses/>.
\r
22 package uk.ac.vamsas.client.simpleclient;
\r
24 import java.io.BufferedInputStream;
\r
25 import java.io.BufferedOutputStream;
\r
26 import java.io.File;
\r
27 import java.io.FileInputStream;
\r
28 import java.io.FileNotFoundException;
\r
29 import java.io.FileOutputStream;
\r
30 import java.io.IOException;
\r
31 import java.io.OutputStream;
\r
32 import java.io.RandomAccessFile;
\r
33 import java.nio.channels.FileChannel;
\r
34 import java.nio.channels.FileLock;
\r
35 import java.nio.channels.ReadableByteChannel;
\r
41 public class NativeLock extends Lock {
\r
43 protected FileLock lock = null;
\r
48 * true means thread will block until a lock is obtained.
\r
50 public NativeLock(File lockfile, boolean block) {
\r
52 // try and get a lock.
\r
57 * if (!lockfile.createNewFile()) {
\r
58 * log.warn("Failed to create locked file "+lockfile); return; }
\r
60 rafile = new RandomAccessFile(lockfile, "rw");
\r
62 lock = rafile.getChannel().lock();
\r
64 lock = rafile.getChannel().tryLock();
\r
65 if (lock == null || !lock.isValid()) {
\r
66 // failed to get lock. Close the file channel
\r
67 log.debug("failed to get lock for " + lockfile);
\r
68 rafile.getChannel().close();
\r
71 } catch (FileNotFoundException e) {
\r
73 log.debug("Lock failed - normal behaviour for windows locking.");
\r
74 // log.error("Error! Couldn't create a lockfile at "
\r
75 // + lockfile.getAbsolutePath(), e);
\r
76 } catch (IOException e) {
\r
77 log.error("Error! Problems with IO when creating a lock on "
\r
78 + lockfile.getAbsolutePath(), e);
\r
79 } // catch (Exception )
\r
82 public boolean isLocked() {
\r
83 if (lock != null && lock.isValid()) {
\r
89 public void release() {
\r
93 public void release(boolean closeChannel) {
\r
97 // channel.close should be called before release() for rigourous locking.
\r
98 if (lock.isValid() && rafile != null && rafile.getFD().valid()
\r
99 && rafile.getChannel() != null) {
\r
100 if (closeChannel && rafile.getChannel().isOpen()) {
\r
104 // just release the lock without doing anything to the channe;l
\r
105 if (lock != null && lock.isValid())
\r
109 } catch (IOException e) {
\r
110 log.warn("Whilst releasing lock", e);
\r
116 * gets Locked Stream for reading from
\r
119 * true to start reading at beginning of file.
\r
120 * @return null if file not locked
\r
121 * @throws IOException
\r
123 public FileInputStream getFileInputStream(boolean atStart) throws IOException {
\r
128 return new FileInputStream(rafile.getFD());
\r
132 * gets Locked stream to write to FileInput always starts at the *end* of the
\r
133 * file (after any truncation)
\r
136 * true means file will be cleared to zero length
\r
137 * @return null if file is not locked
\r
138 * @throws IOException
\r
140 public FileOutputStream getFileOutputStream(boolean clear) throws IOException {
\r
145 rafile.setLength(0);
\r
147 rafile.seek(rafile.length());
\r
148 return new LockedFileOutputStream(rafile.getFD());
\r
152 * return buffered output stream to locked file.
\r
155 * - true means file is truncated to 0 length before writing
\r
158 public BufferedOutputStream getBufferedOutputStream(boolean clear)
\r
159 throws IOException {
\r
160 OutputStream fos = getFileOutputStream(clear);
\r
162 return new BufferedOutputStream(fos);
\r
167 * @see uk.ac.vamsas.client.simpleclient.Lock#finalize()
\r
169 protected void finalize() throws Throwable {
\r
170 release(true); // we explicitly lose the lock here.
\r
171 // log.debug("lock closing through garbage collection ?");
\r
178 * @see uk.ac.vamsas.client.simpleclient.Lock#getLength()
\r
180 public long length() {
\r
183 return rafile.length();
\r
184 } catch (Exception e) {
\r
185 log.debug("getLength exception:", e);
\r
191 public RandomAccessFile getRaFile() throws IOException {
\r
195 log.debug("Failed to getRaFile on " + target);
\r
199 public FileChannel getRaChannel() throws IOException {
\r
201 return rafile.getChannel();
\r
203 log.debug("Failed to getRaChannel on " + target);
\r
207 public boolean isTargetLockFile(File afile) {
\r
208 if (isLocked() && target.equals(afile))
\r