如果在磁盘已满的情况下无法移动失败,则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>
答案 0 :(得分:2)
write(...)
系统调用到完整文件系统的正常行为是失败,并将errno
设置为ENOSPC
。然后,Java会将其转换为IOException
。
但是,您的NFS挂载似乎不像普通文件系统那样报告文件系统已满。以下是一些可以发生这种事情的证据:
如果write syscall没有报告错误,则Java运行时无法检测到该问题。如果这是正在发生的事情,那么它不是Java错误。这可能是您正在使用的NFS服务器或客户端实现的实现中的一个错误。
我希望FileUtils.moveFile
和copyFile
方法能够检测到问题。但是你没有说出你使用的是哪个版本的Apache Commons,所以我无法确定。此外,由于您使用多个线程来移动文件,因此两个线程可能会尝试移动同一个文件,这会导致问题。