Java 磁盘已满时,FileUtils.moveFile不总是引发IOException
FileUtils.moveFile在磁盘已满的情况下无法移动失败文件时,并不总是引发IOException。已创建新文件,但大小为0。下面是代码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
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装载似乎不像普通文件系统那样报告文件系统已满。这里有一些证据表明这种事情可能发生:
我希望使用
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,则实际上不支持这种挂载。