Skip to content

Instantly share code, notes, and snippets.

@gwenn
Created December 5, 2020 13:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gwenn/945c40e551f88e77af0cf141f6ca788e to your computer and use it in GitHub Desktop.
Save gwenn/945c40e551f88e77af0cf141f6ca788e to your computer and use it in GitHub Desktop.
LockedFiles
public class LockedFiles {
/**
* Like {@link java.nio.file.Files#write(Path, byte[], OpenOption...)} but with a lock
*/
public static void write(Path path, byte[] bytes) throws IOException {
if (bytes == null) {
return;
}
log.debug("Writing {}", path);
try (FileChannel chan = FileChannel.open(path, TRUNCATE_EXISTING, WRITE, CREATE, DSYNC);
FileLock lock = chan.lock()) {
assert lock.isValid();
ByteBuffer buf = ByteBuffer.wrap(bytes);
while (0 < buf.remaining()) {
chan.write(buf);
}
chan.force(true);
} finally {
log.debug("Wrote {}", path);
}
}
/**
* Like {@link java.nio.file.Files#readAllBytes} but with a lock
*/
public static byte[] readAllBytes(Path path) throws IOException {
log.debug("Reading {}", path);
try (FileChannel chan = FileChannel.open(path, READ)) {
FileLock lock = chan.lock(0, Long.MAX_VALUE, true);
assert lock.isValid();
long size = chan.size();
if (size > Integer.MAX_VALUE - 8) {
throw new OutOfMemoryError("Required array size too large");
}
byte[] bytes = new byte[(int) size];
ByteBuffer buf = ByteBuffer.wrap(bytes);
//noinspection StatementWithEmptyBody
while (chan.read(buf) >= 0 && buf.hasRemaining()) {
}
return bytes;
} catch (OverlappingFileLockException e) {
log.warn(e.toString(), e);
return new byte[0]; // TODO retry ?
} finally {
log.debug("Read {}", path);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment