在 Windows 上用 Java 并发写入文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/713550/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:38:40  来源:igfitidea点击:

Concurrent file write in Java on Windows

javafile-ioportabilityconcurrency

提问by Andrei Vajna II

What happens when you concurrently open two (or more) FileOutputStreams on the same file?

当您在同一个文件上同时打开两个(或更多)FileOutputStreams 时会发生什么?

The Java APIsays this:

Java的API这样说:

Some platforms, in particular, allow a file to be opened for writing by only one FileOutputStream (or other file-writing object) at a time.

特别是某些平台,一次只允许一个 FileOutputStream(或其他文件写入对象)打开一个文件进行写入。

I'm guessing Windows isn't such a platform, because I have two threads that read some big file (each one a different one) then write it to the same output file. No exception is thrown, the file is created and seems to contain chunks from both input files.

我猜 Windows 不是这样的平台,因为我有两个线程读取一些大文件(每个都不同),然后将其写入同一个输出文件。没有异常抛出,文件被创建并且似乎包含来自两个输入文件的块。

Side questions:

侧面问题:

  • Is this true for Unix, too?
  • And since I want the behaviour to be the same (actually I want one thread to write correctly and the other to be warned of the conflict), how can I determine that the file is already opened for writing?
  • 对于 Unix 也是如此吗?
  • 并且由于我希望行为相同(实际上我希望一个线程正确写入而另一个线程被警告冲突),我如何确定该文件已经打开进行写入?

采纳答案by erickson

There's not a reliable, cross-platform way to be passively notified when a file has another writer—i.e., raise an exception if a file is already open for writing. There are a couple of techniques that help you actively check for this, however.

没有一种可靠的、跨平台的方式可以在文件有另一个写入器时被动地通知——即,如果文件已经打开进行写入,则引发异常。但是,有几种技术可以帮助您主动检查这一点。

If multiple processes (which can be a mix of Java and non-Java) might be using the file, use a FileLock. A key to using file locks successfully is to remember that they are only "advisory". The lock is guaranteed to be visible if you check for it, but it won't stop you from doing things to the file if you forget. All processes that access the file should be designed to use the locking protocol.

如果多个进程(可以是 Java 和非 Java 的混合)可能正在使用该文件,请使用FileLock. 成功使用文件锁的一个关键是记住它们只是“建议”。如果您检查锁定,则保证它是可见的,但如果您忘记了,它不会阻止您对文件进行操作。所有访问文件的进程都应该设计为使用锁定协议。

If a single Java process is working with the file, you can use the concurrency tools built into Java to do it safely. You need a map visible to all threads that associates each file name with its corresponding lock instance. The answers to a related questioncan be adapted easily to do this with Fileobjects or canonical pathsto files. The lock object could be a FileOutputStream, some wrapper around the stream, or a ReentrantReadWriteLock.

如果单个 Java 进程正在处理该文件,您可以使用 Java 中内置的并发工具来安全地执行此操作。您需要一个对所有线程可见的映射,该映射将每个文件名与其对应的锁实例相关联。相关问题的答案可以很容易地修改为使用File对象或文件的规范路径来做到这一点。锁定对象可以是 a FileOutputStream,流周围的一些包装器,或ReentrantReadWriteLock.

回答by Brian Agnew

I would be wary of letting the OS determine file status for you (since this is OS-dependent). If you've got a shared resource I would restrict access to it using a Re-entrant lock

我会担心让操作系统为您确定文件状态(因为这取决于操作系统)。如果你有一个共享资源,我会使用重入锁来限制对它的访问

Using this lock means one thread can get the resource (file) and write to it. The next thread can check for this lock being held by another thread, and/or block indefinitely until the first thread releases it.

使用这个锁意味着一个线程可以获取资源(文件)并写入它。下一个线程可以检查这个锁是否被另一个线程持有,和/或无限期地阻塞,直到第一个线程释放它。

Windows (I think) would restrict two processes writing to the same file. I don't believe Unix would do the same.

Windows(我认为)会限制两个进程写入同一个文件。我不相信 Unix 会这样做。

回答by Nicolas C

If the 2 threads you are talking about are in the same JVM, then you could have a boolean variable somewhere that is accessed by both threads.

如果您正在谈论的 2 个线程在同一个 JVM 中,那么您可以在某处有一个布尔变量,两个线程都可以访问该变量。

回答by Peter Lawrey

Unix allows concurrent writers to the same file.

Unix 允许并发写入同一个文件。

You shouldn't be attempting to write to the same file more than once. If you are you have a design flaw.

您不应多次尝试写入同一个文件。如果你是你有一个设计缺陷。