使用Java在Windows中将原子字符串附加到文件

使用Java在Windows中将原子字符串附加到文件,java,windows,multithreading,scala,Java,Windows,Multithreading,Scala,据介绍,Windows上的小文件附件是原子的 我试图在Scala/Java中利用这一点,以避免在向文件追加小int时锁定 我发现来自多个线程的使用FileOutputStream(…,true)的写入正在被交错,尽管上面链接的问题表明它们应该是原子的 可以在Scala中找到用于此的测试线束 关键代码是: def invoked(id: Int, path: String) = { val writer = new FileOutputStream(path, true) val byte

据介绍,Windows上的小文件附件是原子的

我试图在Scala/Java中利用这一点,以避免在向文件追加小int时锁定

我发现来自多个线程的使用
FileOutputStream(…,true)
的写入正在被交错,尽管上面链接的问题表明它们应该是原子的

可以在Scala中找到用于此的测试线束

关键代码是:

def invoked(id: Int, path: String) = {
  val writer = new FileOutputStream(path, true)
  val bytes = (id.toString + ';').getBytes(Charset.defaultCharset())
  writer.write(bytes)
  writer.close()
}
。。。我希望“调用的”在没有锁定的情况下是线程安全的

同样的Java/Scala代码在Linux上实现了原子文件附件(正如POSIX上的小文件附件是原子的),因此差异似乎出现在
FileOutputStream
的本机实现中


可能是
FileOutputStream
没有将正确的标志传递给Windows?有人知道怎么做吗?我是否必须编写JNI DLL才能使其正常工作,或者是否有一种方法可以使用Java的标准库执行此操作?

写入操作行为取决于文件打开标志。在Windows上,您需要使用FILE_APPEND_DATA标志或使用特殊常量来实现APPEND。Posix需要O_追加标志。尽管Java对append参数有bool值,但下面的注释解释了它的源代码


我认为Windows和POSIX都提供了这种保证,这对我来说已经足够了。请看,最安全的方法是让生产者线程“写入”单个消费者线程。单个使用者线程处理实际的文件写入。@GilbertLeBlanc这是一个不错的方法,是的。然而,如果O/S提供了原子文件写入(并且它确实声称这样做),那么利用它会更有效。我已经实施了一种更为传统的解决方法。这个问题是关于如何使原子文件写入方法在Java中工作。
FileDispatcherImpl(boolean append) {
    /* append is ignored */
}