当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) 在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中是否存在一个错误,由于该错误,当应用程序移动文件失败时,它不会通知应用程序?
发布于 2017-01-13 13:54:18
对于一个完整的文件系统,write(...) syscall的正常行为是失败,并将errno设置为ENOSPC。然后,Java会将其转换为IOException。
但是,您的NFS挂载似乎没有像正常的文件系统那样报告文件系统。这里有一些证据表明这类事情可能会发生:
如果写syscall没有报告错误,Java运行时就无法检测问题。如果这就是正在发生的事情,那么它就不是Java错误。它可能是您正在使用的NFS服务器或客户端实现的实现中的一个bug。
我希望FileUtils.moveFile和copyFile方法能够检测到问题。但是,您并没有说您使用的是哪个版本的,所以我不能肯定这一点。另外,由于您使用多个线程来移动文件,因此可能有两个线程试图移动同一个文件,这会导致问题。
https://stackoverflow.com/questions/41629445
复制相似问题