Linux 在 Scala 中锁定和写入文件的最佳方式

The optimal way to lock and write to a file in Scala on Linux

我很难找到使用 Scala 在 Linux 上执行任何高级文件系统操作的正确方法。

我真的想不通下面的伪代码是否能最好地描述这个:

with fd = open(path, append | create):
    with flock(fd, exclusive_lock):
        fd.write(string)

基本上以追加模式打开一个文件(如果它不存在则创建它),获得一个独占锁并写入它(使用隐式解锁然后关闭)。

如果我知道我的程序将 运行 仅在 linux 上运行,是否有一种简单、干净且高效的方法来执行此操作? (最好不看一眼就提供应该处理的异常)。

编辑:

据我所见和测试,我得到的答案是正确的。然而,它非常冗长,所以我将其标记为 ok,但我将这段代码留在这里,这是我最终使用的代码(不确定它是否正确,但据我所知,它完成了我所做的一切需要):

  val fc  = FileChannel.open(Paths.get(file_path), StandardOpenOption.CREATE, StandardOpenOption.APPEND)
  try {
    fc.lock()
    fc.write(ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8)))
  } finally { fc.close() }

您可以使用 FileChannel.lock and FileLock 来获得您想要的:

import java.nio.ByteBuffer
import java.nio.channels.FileChannel
import java.nio.charset.StandardCharsets
import java.nio.file.{Path, Paths, StandardOpenOption}

import scala.util.{Failure, Success, Try}

object ExclusiveFsWrite {
  def main(args: Array[String]): Unit = {
    val path = Paths.get("/tmp/file")
    val buffer = ByteBuffer.wrap("Some text data here".getBytes(StandardCharsets.UTF_8))

    val fc = getExclusiveFileChannel(path)
    try {
      fc.write(buffer)
    }
    finally {
      // channel close will also release a lock
      fc.close()
    }

    ()
  }

  private def getExclusiveFileChannel(path: Path): FileChannel = {
    // Append if exist or create new file (if does not exist)
    val fc = FileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.APPEND,
      StandardOpenOption.CREATE)
    if (fc.size > 0) {
      // set position to the end
      fc.position(fc.size - 1)
    }
    // get an exclusive lock
    Try(fc.lock()) match {
      case Success(lock) =>
        println("Is shared lock: " + lock.isShared)
        fc
      case Failure(ex) =>
        Try(fc.close())
        throw ex
    }
  }
}