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

时间:2017-10-29 15:56:11

标签: java linux scala file filesystems

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

我真的无法弄清楚下面的伪代码是否最好描述:

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

基本上以附加模式打开文件(如果它不存在则创建它),获取它的独占锁并写入它(隐式解锁并在之后关闭)。

如果我知道我的程序只在linux上运行,是否有一种简单,干净,高效的方法? (最好不要瞥一眼提供应该处理的例外情况。)

编辑:

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

  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() }

1 个答案:

答案 0 :(得分:2)

您可以使用FileChannel.lockFileLock来获得您想要的内容:

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
    }
  }
}