【问题标题】:Windows vs OSX FileLock OutputStreamWriterWindows vs OSX FileLock OutputStreamWriter
【发布时间】:2013-02-20 10:45:18
【问题描述】:

我编写了一个访问文件的 java 应用程序,而其他 VM 中的其他进程尝试执行相同操作。因此我使用 FileLock 类:

FileOutputStream fos = new  FileOutputStream(filePath,append);
    FileChannel f = fos.getChannel();
    FileLock lock;

    while ((lock = f.tryLock()) == null){
        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    OutputStreamWriter out = new OutputStreamWriter( new FileOutputStream(filePath,append));
    out.write(textToWrite);
    out.close();
    lock.release();

在 Mac OSX 上一切正常,但是当我在 Windows 7 上运行代码时,它会在该行抛出 IOException

out.close();

,尝试刷新时。

java.io.IOException: The process cannot access the file because another process has locked a portion of the file
at java.io.FileOutputStream.writeBytes(Native Method)

How does FileLock work?了解,实际获取锁的方式是

f.tryLock()

禁止我访问它,因为另一个进程(显然是这个)具有排他锁。

现在这让我觉得很矛盾——当获得锁的实际行为阻碍我写文件时,我如何获得一个独占锁以使我能够写入文件而不会有其他进程弄乱它的危险这样做?

那么为什么它可以在 Mac OS 上运行而不是在 Windows 上呢?我从 JavaDocs 中知道 FileLock 类存在操作系统特定的差异和困难,但肯定不是针对其设计的功能。 既然不能这样,我做错了,我在这里寻求你的帮助。

谢谢, M

【问题讨论】:

    标签: java windows ioexception filelock


    【解决方案1】:

    在 UNIX 上没有文件锁定。:http://www.coderanch.com/t/551144/java/java/File-lock-doesn-prevent-threads。事实上,在 UNIX 上,您可以从进程下删除文件,它甚至可能不会注意到...
    因此,您需要使用可以检查存在的锁定文件。
    矛盾的是,您的代码在 Windows 上运行,但在 UNIX(即 Mac OS)上运行,异常应该是尝试写入被另一个进程锁定的文件的预期结果。

    【讨论】:

    • 感谢您的回复。不过,我不确定我是否完全理解你和 coderanch 的帖子。您的意思是“没有文件锁定”是 UNIX 不提供该功能,因此我必须使用 FileLock 类来提供它?而且,根据您的论点,windows 提供了文件锁定的功能,因此我不需要使用 FileLock?如果我理解你,那么它甚至更进一步,尝试在 Windows 上使用 FIleLock 会引发异常?
    • FileLock 类是非常特定于操作系统的——在 UNIX 上它绝对什么都不做;我管理,这有点没用。在 Windows 上,它有自己的问题,如您提到的帖子中所述。简而言之,它有点狡猾。所以我建议使用锁定文件 - 即在某处写一些东西并将其用作外部互斥体。
    • 你有比那篇文章更多的证据吗?请原谅这个人,但我不认为 coderanch.com 特别可靠,因为我在那里看到了大量的错误信息。如果文件锁定方法实际上没有调用 Unix 系统的底层 flock()lockf() 函数或类似的函数,那么为什么会有像 Java bug 4877242 之类的错误(“文件锁定在 Linux 上是每个线程的”)?跨度>
    • 有很多信息,但这是在互联网上。 Ubuntu forumsanother article 上的一些东西,您可以尝试使用测试用例和 Oracle 上的错误报告 - 这是一个古老的但解释了根本问题。希望对您有所帮助。
    猜你喜欢
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    相关资源
    最近更新 更多