在Windows上用Java并发文件写入
问题内容:
当您同时打开同一文件上的两个(或多个)FileOutputStreams时会发生什么?
在Java的API这样说:
特别是某些平台,一次只允许一个FileOutputStream(或其他文件写入对象)打开一个文件进行写入。
我猜想Windows并不是一个这样的平台,因为我有两个线程读取一个大文件(每个都不同),然后将其写入相同的输出文件。没有异常被抛出,文件被创建并且似乎包含两个输入文件中的块。
附带问题:
- Unix也是如此吗?
- 并且由于我希望行为相同(实际上我希望一个线程正确写入,而另一个线程被警告发生冲突),那么如何确定该文件已被打开以进行写入?
问题答案:
当文件有另一个编写器时,没有一种可靠的跨平台方式来被动地通知用户,即,如果文件已经打开可写,则会引发异常。但是,有两种技术可以帮助您主动进行检查。
如果该文件可能有多个进程(可能是Java和非Java的混合),请使用FileLock
。成功使用文件锁的关键是记住它们只是“建议”。如果您检查该锁,可以确保该锁是可见的,但是如果您忘记了它,它也不会阻止您对文件执行操作。访问文件的所有进程都应设计为使用锁定协议。
如果单个Java进程正在处理该文件,则可以使用Java内置的并发工具来安全地进行处理。您需要一个对所有线程可见的映射,该映射将每个文件名与其对应的锁实例相关联。通过使用对象或文件的规范路径,可以轻松调整相关问题的答案,以实现此File
目的。锁定对象可以是,流周围的包装器或。FileOutputStream
ReentrantReadWriteLock