Java 无法访问文件,因为正在使用

Java 无法访问文件,因为正在使用,java,file,csv,exception,Java,File,Csv,Exception,我正在给我的java程序写一个日志(csv格式)。 记录器工作正常,我有一个问题 当我试图写入文件并同时打开文件时,程序将崩溃,这听起来很合乎逻辑。 当我这样做时,我得到了一个例外:“进程无法访问该文件,因为它正被另一个进程使用” 我的问题是,即使有人打开文件,是否仍有人继续写? private void close() throws IOException { RandomAccessFile rf; rf = new RandomAccessFile(file, "rw");

我正在给我的java程序写一个日志(csv格式)。 记录器工作正常,我有一个问题

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

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

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();

}
谢谢

更新:

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

我更改了close()函数: 1.添加了fileChannel和FileLock。 2.i忽略行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: 现在我发现,如果我将函数更改为该值(close更改为flush),则其工作:

   private void close()  {
    try {
        if (bw != null) {
            bw.flush(); 
            bw = null;
        }
        if (fw != null) {
            fw.flush();
            fw = null;
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}
最好的选择是什么?

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();

}
即使有其他东西打开了文件,是否仍有继续写入的空间

不是用Java

要编写文件,必须先打开它。如果因为操作系统不允许而无法打开它。。。因为有别的东西打开了它。。。那你就不能写了

在此场景中,您应该考虑打开一个不同的日志文件。


请注意,这种情况发生在Windows中,因为Java遵循正常的窗口实践,并且在默认情况下使用独占(强制)锁打开文件。除了改变Java。。。其他所有打开类似文件的Windows应用程序。。。你被卡住了


更新

事实证明,可能有一种方法

  • 阅读以下问答:
  • 使用
    FileChannel。按说明打开
    ,但使用允许您在不禁止其他写入程序的情况下写入的标志。比如说

       FileChannel.open(path, WRITE)
    

    诀窍是你不需要任何
    NOSHARE.*
    选项

  • 警告:我还没试过这个

    即使有其他东西打开了文件,是否仍有继续写入的空间

    不是用Java

    要编写文件,必须先打开它。如果因为操作系统不允许而无法打开它。。。因为有别的东西打开了它。。。那你就不能写了

    在此场景中,您应该考虑打开一个不同的日志文件。


    请注意,这种情况发生在Windows中,因为Java遵循正常的窗口实践,并且在默认情况下使用独占(强制)锁打开文件。除了改变Java。。。其他所有打开类似文件的Windows应用程序。。。你被卡住了


    更新

    事实证明,可能有一种方法

  • 阅读以下问答:
  • 使用
    FileChannel。按说明打开
    ,但使用允许您在不禁止其他写入程序的情况下写入的标志。比如说

       FileChannel.open(path, WRITE)
    

    诀窍是你不需要任何
    NOSHARE.*
    选项


  • 警告:我没有尝试过此操作。

    解决问题:在继续编写时尝试打开:

    • 如果需要固定数据,可以复制文件(通过shell),然后读取

    • 如果您希望将来写入数据,则必须保持相同的输出:尝试将正常输出重定向到可以存储和读取的位置

    也许有图书馆存在。看起来像是T形管和T形管

    例如,见:

    • 要将log4j重定向到所需位置,请参见以下示例:

    解决问题:继续写入时尝试打开:

    • 如果需要固定数据,可以复制文件(通过shell),然后读取

    • 如果您希望将来写入数据,则必须保持相同的输出:尝试将正常输出重定向到可以存储和读取的位置

    也许有图书馆存在。看起来像是T形管和T形管

    例如,见:

    • 要将log4j重定向到所需位置,请参见以下示例:

    正如@guilloum所说,您可以使用类似log4j的库


    但是如果您想用Java实现您的解决方案,您可以使用observer模式并异步编写日志。

    正如@guillaume所说,您可以使用类似log4j的库


    但是如果您想用Java实现您的解决方案,您可以使用observer模式异步编写日志。

    请显示您的代码。请显示您的代码。