因使用而无法访问文件

时间:2017-03-19 08:28:01

标签: java file csv exception

我正在为我的java程序编写一个记录器(采用csv格式)。 记录器工作正常,我有一个问题。

当我尝试写入文件并同时打开文件时,程序会崩溃,这听起来很合乎逻辑。 当我这样做时,我得到了一个例外:“进程无法访问该文件,因为它正被另一个进程使用”。

我的问题是,即使有人打开文件,是否还有继续写作?

感谢。

更新

我想我解决了这个问题。 每次写入文件后(使用bufferedWriter和FileWriter),我都会调用close()函数来关闭bufferedWriter和FileWriter。

我更改了close()函数: 1.添加了fileChannel和FileLock。 2. Igonore线bw.close();

可以不关闭bufferWriter(bw)?以后可以出现任何问题吗?

private void close() throws IOException {
    RandomAccessFile rf;
    rf = new RandomAccessFile(file, "rw");
    fileChannel = rf.getChannel();
    lock = fileChannel.lock();
    try {
        if (bw != null) {
            //    bw.close();  The line i ignored.
            bw = null;
        }
        if (fw != null) {
            fw.close();
            fw = null;
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }

    lock.release();

}

更新2: 现在我发现如果我将函数更改为(关闭更改为flush),它的工作:

   private void close()  {
    try {
        if (bw != null) {
            bw.flush(); 
            bw = null;
        }
        if (fw != null) {
            fw.flush();
            fw = null;
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

什么是最佳选择?

3 个答案:

答案 0 :(得分:1)

  

即使有其他东西打开文件,是否还有继续写作?

不是Java。

要编写文件,必须先将其打开。如果你不能打开它,因为操作系统不会允许它...因为其他东西已经打开它......那么你就无法达到可以写它的程度。

在这种情况下,您应该考虑打开另一个日志文件。

请注意,这种情况发生在Windows中,因为Java遵循正常的Window实践并默认使用独占(强制)锁打开文件。没有更改Java ...以及打开这样的文件的每个其他Windows应用程序......你被困住了。

<强>更新

事实证明可能是的一种方式。

  1. 阅读此问与答:https://stackoverflow.com/a/22648514/139985
  2. 如上所述使用FileChannel.open,但使用允许您在不禁止其他编写者的情况下编写的标记。例如

       FileChannel.open(path, WRITE)
    

       FileChannel.open(path, WRITE, APPEND)
    

    诀窍在于您不需要任何NOSHARE_*选项。

  3. CAVEAT:我没试过。

答案 1 :(得分:1)

扭转问题:尝试在继续写作时打开:

  • 如果你想要固定数据,你可以复制文件(通过shell),然后阅读它;

  • 如果您想要未来的书面数据,则必须保持相同的输出:尝试将正常输出重定向到您可以存储和读取的内容。

也许存在一些图书馆。它看起来像发球和发球。

参见例如: Could I duplicate or intercept an output stream in Java?

  • 用于将log4j重定向到您想要的内容,例如:

How do I redirect log4j output to my HttpServletResponse output stream?

答案 2 :(得分:1)

正如@guillaume所说,你可以使用像log4j这样的库。

但是如果要在Java中实现解决方案,可以使用观察者模式并将日志写为异步。