磁盘已满时,FileUtils.moveFile并不总是抛出IOException

时间:2017-01-13 07:29:53

标签: java multithreading ioexception

如果在磁盘已满的情况下无法移动失败,则FileUtils.moveFile并不总是抛出IOException。创建新文件但大小为0.下面是代码

void  function1 (String filePath1, String dir) 
{
    File file1= new File( filePath1);
    File file2= new File( dir, file1.getName() );

    FileUtils.moveFile( file1, file2);
}

多个线程正在使用上述功能。每个线程都有一个唯一的filePath1值。磁盘存储由NFS服务器控制。因此,当移动文件失败并创建空文件时,某些线程会抛出异常(文件名已被屏蔽)。

  

无法将完整内容从'######'复制到'######'预计长度:239?实际:0

     

at org.apache.commons.io.FileUtils.doCopyFile(FileUtils.java:1164)

     

at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1088)

     

at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:1040)

     

at org.apache.commons.io.FileUtils.moveFile(FileUtils.java:2993)

     

在function1

但是其中一些不会抛出任何异常,目标文件为空。

为了验证这一点,我添加了文件大小检查。

void  function1 (String filePath1, String dir)
{
    File file1= new File( filePath1);
    File file2= new File( dir, file1.getName() );
    long sizeOfFile1 = FileUtils.sizeOf( file1);
    FileUtils.moveFile( file1, file2);
    long sizeOfFile2 = FileUtils.sizeOf( file2);

    if( sizeOFile1 != sizeOfFile2 )
          LOG.error( "###### expected size " + sizeOFile1 + " but actual size " +  sizeOfFile2 + " for thread " + ######## );
        throw new IOException();

    }
}

在此之后,之前没有抛出异常的每个线程都开始在上面的函数中打印错误

  预期大小239但线程的实际大小为0

所以我想了解在NFS存储的情况下是否还有其他事情可以做,或者JVM中是否存在错误,因为当它无法移动文件时它不通知应用程序? / p>

1 个答案:

答案 0 :(得分:2)

write(...)系统调用到完整文件系统的正常行为是失败,并将errno设置为ENOSPC。然后,Java会将其转换为IOException

但是,您的NFS挂载似乎不像普通文件系统那样报告文件系统已满。以下是一些可以发生这种事情的证据:

如果write syscall没有报告错误,则Java运行时无法检测到该问题。如果这是正在发生的事情,那么它不是Java错误。这可能是您正在使用的NFS服务器或客户端实现的实现中的一个错误。

我希望FileUtils.moveFilecopyFile方法能够检测到问题。但是你没有说出你使用的是哪个版本的Apache Commons,所以我无法确定。此外,由于您使用多个线程来移动文件,因此两个线程可能会尝试移动同一个文件,这会导致问题。

相关问题