FileDocCategorySizeDatePackage
LockableFileWriter.javaAPI DocAndroid 1.5 API11795Wed May 06 22:42:46 BST 2009org.apache.commons.io.output

LockableFileWriter

public class LockableFileWriter extends Writer
FileWriter that will create and honor lock files to allow simple cross thread file lock handling.

This class provides a simple alternative to FileWriter that will use a lock file to prevent duplicate writes.

By default, the file will be overwritten, but this may be changed to append. The lock directory may be specified, but defaults to the system property java.io.tmpdir. The encoding may also be specified, and defaults to the platform default.

author
Scott Sanders
author
Michael Salmon
author
Jon S. Stevens
author
Daniel Rall
author
Stephen Colebourne
author
Andy Lehane
version
$Id: LockableFileWriter.java 610010 2008-01-08 14:50:59Z niallp $

Fields Summary
private static final String
LCK
The extension for the lock file.
private final Writer
out
The writer to decorate.
private final File
lockFile
The lock file.
Constructors Summary
public LockableFileWriter(String fileName)
Constructs a LockableFileWriter. If the file exists, it is overwritten.

param
fileName the file to write to, not null
throws
NullPointerException if the file is null
throws
IOException in case of an I/O error


                                            
         
        this(fileName, false, null);
    
public LockableFileWriter(String fileName, boolean append)
Constructs a LockableFileWriter.

param
fileName file to write to, not null
param
append true if content should be appended, false to overwrite
throws
NullPointerException if the file is null
throws
IOException in case of an I/O error

        this(fileName, append, null);
    
public LockableFileWriter(String fileName, boolean append, String lockDir)
Constructs a LockableFileWriter.

param
fileName the file to write to, not null
param
append true if content should be appended, false to overwrite
param
lockDir the directory in which the lock file should be held
throws
NullPointerException if the file is null
throws
IOException in case of an I/O error

        this(new File(fileName), append, lockDir);
    
public LockableFileWriter(File file)
Constructs a LockableFileWriter. If the file exists, it is overwritten.

param
file the file to write to, not null
throws
NullPointerException if the file is null
throws
IOException in case of an I/O error

        this(file, false, null);
    
public LockableFileWriter(File file, boolean append)
Constructs a LockableFileWriter.

param
file the file to write to, not null
param
append true if content should be appended, false to overwrite
throws
NullPointerException if the file is null
throws
IOException in case of an I/O error

        this(file, append, null);
    
public LockableFileWriter(File file, boolean append, String lockDir)
Constructs a LockableFileWriter.

param
file the file to write to, not null
param
append true if content should be appended, false to overwrite
param
lockDir the directory in which the lock file should be held
throws
NullPointerException if the file is null
throws
IOException in case of an I/O error

        this(file, null, append, lockDir);
    
public LockableFileWriter(File file, String encoding)
Constructs a LockableFileWriter with a file encoding.

param
file the file to write to, not null
param
encoding the encoding to use, null means platform default
throws
NullPointerException if the file is null
throws
IOException in case of an I/O error

        this(file, encoding, false, null);
    
public LockableFileWriter(File file, String encoding, boolean append, String lockDir)
Constructs a LockableFileWriter with a file encoding.

param
file the file to write to, not null
param
encoding the encoding to use, null means platform default
param
append true if content should be appended, false to overwrite
param
lockDir the directory in which the lock file should be held
throws
NullPointerException if the file is null
throws
IOException in case of an I/O error

        super();
        // init file to create/append
        file = file.getAbsoluteFile();
        if (file.getParentFile() != null) {
            FileUtils.forceMkdir(file.getParentFile());
        }
        if (file.isDirectory()) {
            throw new IOException("File specified is a directory");
        }
        
        // init lock file
        if (lockDir == null) {
            lockDir = System.getProperty("java.io.tmpdir");
        }
        File lockDirFile = new File(lockDir);
        FileUtils.forceMkdir(lockDirFile);
        testLockDir(lockDirFile);
        lockFile = new File(lockDirFile, file.getName() + LCK);
        
        // check if locked
        createLock();
        
        // init wrapped writer
        out = initWriter(file, encoding, append);
    
Methods Summary
public voidclose()
Closes the file writer.

throws
IOException if an I/O error occurs

        try {
            out.close();
        } finally {
            lockFile.delete();
        }
    
private voidcreateLock()
Creates the lock file.

throws
IOException if we cannot create the file

        synchronized (LockableFileWriter.class) {
            if (!lockFile.createNewFile()) {
                throw new IOException("Can't write file, lock " +
                        lockFile.getAbsolutePath() + " exists");
            }
            lockFile.deleteOnExit();
        }
    
public voidflush()
Flush the stream.

throws
IOException if an I/O error occurs

        out.flush();
    
private java.io.WriterinitWriter(java.io.File file, java.lang.String encoding, boolean append)
Initialise the wrapped file writer. Ensure that a cleanup occurs if the writer creation fails.

param
file the file to be accessed
param
encoding the encoding to use
param
append true to append
return
The initialised writer
throws
IOException if an error occurs

        boolean fileExistedAlready = file.exists();
        OutputStream stream = null;
        Writer writer = null;
        try {
            if (encoding == null) {
                writer = new FileWriter(file.getAbsolutePath(), append);
            } else {
                stream = new FileOutputStream(file.getAbsolutePath(), append);
                writer = new OutputStreamWriter(stream, encoding);
            }
        } catch (IOException ex) {
            IOUtils.closeQuietly(writer);
            IOUtils.closeQuietly(stream);
            lockFile.delete();
            if (fileExistedAlready == false) {
                file.delete();
            }
            throw ex;
        } catch (RuntimeException ex) {
            IOUtils.closeQuietly(writer);
            IOUtils.closeQuietly(stream);
            lockFile.delete();
            if (fileExistedAlready == false) {
                file.delete();
            }
            throw ex;
        }
        return writer;
    
private voidtestLockDir(java.io.File lockDir)
Tests that we can write to the lock directory.

param
lockDir the File representing the lock directory
throws
IOException if we cannot write to the lock directory
throws
IOException if we cannot find the lock file

        if (!lockDir.exists()) {
            throw new IOException(
                    "Could not find lockDir: " + lockDir.getAbsolutePath());
        }
        if (!lockDir.canWrite()) {
            throw new IOException(
                    "Could not write to lockDir: " + lockDir.getAbsolutePath());
        }
    
public voidwrite(int idx)
Write a character.

param
idx the character to write
throws
IOException if an I/O error occurs

        out.write(idx);
    
public voidwrite(char[] chr)
Write the characters from an array.

param
chr the characters to write
throws
IOException if an I/O error occurs

        out.write(chr);
    
public voidwrite(char[] chr, int st, int end)
Write the specified characters from an array.

param
chr the characters to write
param
st The start offset
param
end The number of characters to write
throws
IOException if an I/O error occurs

        out.write(chr, st, end);
    
public voidwrite(java.lang.String str)
Write the characters from a string.

param
str the string to write
throws
IOException if an I/O error occurs

        out.write(str);
    
public voidwrite(java.lang.String str, int st, int end)
Write the specified characters from a string.

param
str the string to write
param
st The start offset
param
end The number of characters to write
throws
IOException if an I/O error occurs

        out.write(str, st, end);