Add support for disabling fsync in atomicWrite

Sometimes we want to ensure the write is atomic but don't care about
durability.

Signed-off-by: Graham <gpe@openrs2.org>
master
Graham 2 years ago
parent 4252bf0dbc
commit 4aa181b91a
  1. 30
      util/src/main/kotlin/org/openrs2/util/io/PathExtensions.kt

@ -107,25 +107,36 @@ public inline fun <T> Path.useTempFile(
} }
} }
public inline fun <T> Path.atomicWrite(f: (Path) -> T): T { public inline fun <T> Path.atomicWrite(
sync: Boolean = true,
f: (Path) -> T,
): T {
parent.useTempFile(".$fileName", ".tmp") { tempFile -> parent.useTempFile(".$fileName", ".tmp") { tempFile ->
val result = f(tempFile) val result = f(tempFile)
if (sync) {
tempFile.fsync() tempFile.fsync()
}
Files.move(tempFile, this, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING) Files.move(tempFile, this, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING)
if (sync) {
try { try {
parent.fsync() parent.fsync()
} catch (ex: IOException) { } catch (ex: IOException) {
// can't fsync directories on (at least) Windows and jimfs // can't fsync directories on (at least) Windows and jimfs
} }
}
return result return result
} }
} }
public inline fun <T> Path.useAtomicBufferedWriter(vararg options: OpenOption, f: (BufferedWriter) -> T): T { public inline fun <T> Path.useAtomicBufferedWriter(
return atomicWrite { path -> vararg options: OpenOption,
sync: Boolean = true,
f: (BufferedWriter) -> T,
): T {
return atomicWrite(sync) { path ->
Files.newBufferedWriter(path, *options).use { writer -> Files.newBufferedWriter(path, *options).use { writer ->
f(writer) f(writer)
} }
@ -135,17 +146,22 @@ public inline fun <T> Path.useAtomicBufferedWriter(vararg options: OpenOption, f
public inline fun <T> Path.useAtomicBufferedWriter( public inline fun <T> Path.useAtomicBufferedWriter(
cs: Charset, cs: Charset,
vararg options: OpenOption, vararg options: OpenOption,
f: (BufferedWriter) -> T sync: Boolean = true,
f: (BufferedWriter) -> T,
): T { ): T {
return atomicWrite { path -> return atomicWrite(sync) { path ->
Files.newBufferedWriter(path, cs, *options).use { writer -> Files.newBufferedWriter(path, cs, *options).use { writer ->
f(writer) f(writer)
} }
} }
} }
public inline fun <T> Path.useAtomicOutputStream(vararg options: OpenOption, f: (OutputStream) -> T): T { public inline fun <T> Path.useAtomicOutputStream(
return atomicWrite { path -> vararg options: OpenOption,
sync: Boolean = true,
f: (OutputStream) -> T,
): T {
return atomicWrite(sync) { path ->
Files.newOutputStream(path, *options).use { output -> Files.newOutputStream(path, *options).use { output ->
f(output) f(output)
} }

Loading…
Cancel
Save