Java 磁盘已满时,FileUtils.moveFile不总是引发IOException

Java 磁盘已满时,FileUtils.moveFile不总是引发IOException,java,multithreading,ioexception,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, fi

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

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

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

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

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

在功能1

但其中一些不会引发任何异常,并且目标文件为空

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

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中是否存在错误,导致它在无法移动文件时不会通知应用程序?

写入(…)的正常行为对完整文件系统的系统调用将失败,并将
errno
设置为
ENOSPC
。Java随后会将其转换为
IOException

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

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



我希望使用
FileUtils.moveFile
copyFile
方法来检测问题。但是,您没有说您使用的是哪个版本的ApacheCommons,所以我不能确定。另外,由于您使用多个线程移动文件,因此可能有两个线程试图移动同一个文件,这会导致问题

检查此项:
File
类有一些方法来检查DiskSpace使用java.nio.File.FilesThanx获取链接。但该程序的目的不是检测磁盘何时已满。这里的问题是FileUtils.moveFile函数在无法移动文件时并不总是抛出IOException。在一个线程中它抛出异常,在另一个线程中它不抛出异常。在两个线程中,目标文件都是空的。@rkosegi:在“FileUtils.moveFile”的描述中,它写为“IOException-如果在移动文件时发生IO错误”,并将其抛出其中一个线程。在java.nio.file.Files.move函数“IOException-如果发生I/O错误”的描述中也写了同样的内容。所以我想了解为什么它不总是有效。它是哪个版本的FileUtils?您可以指定maven依赖项吗?例如,
org.apache.commons commons io 1.3.2
提供了
FileUtils.copyFile(file1,file2)
,它比较了文件大小,并可能相应地抛出IOException。NFS问题的有趣写入。糟糕的是,它是基于从
localhost
共享的文件的NFS挂载的——如果您将其报告为bug,则实际上不支持这种挂载。