Java FileChannel.size()vs File.length()-在FileChannel.truncate()之后
我在考虑改变我的处境。然后我决定我的处境需要它自己的问题和希望的答案。调用Java FileChannel.size()vs File.length()-在FileChannel.truncate()之后,java,filesize,Java,Filesize,我在考虑改变我的处境。然后我决定我的处境需要它自己的问题和希望的答案。调用FileChannel.truncate()以减小文件大小后,我调用FileChannel.size(),关闭FileChannel,然后调用file.length()。该文件在整个操作过程中都存在FileChannel.size()总是准确的。在极少数情况下,File.length()将返回truncate()之前的文件大小 下面是显示这种情况的代码 public static void truncate(File fi
FileChannel.truncate()
以减小文件大小后,我调用FileChannel.size()
,关闭FileChannel
,然后调用file.length()
。该文件在整个操作过程中都存在FileChannel.size()
总是准确的。在极少数情况下,File.length()
将返回truncate()
之前的文件大小
下面是显示这种情况的代码
public static void truncate(File file, long size) throws IOException
{
FileChannel channel;
Path path;
long channelSize, fileLengthOpen, fileLengthClosed;
path = file.toPath();
channel = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
try
{
channel.truncate(size);
channelSize = channel.size();
fileLengthOpen = file.length();
}
finally
{
channel.close();
}
fileLengthClosed = file.length();
if ((channelSize != size) || (fileLengthOpen != size) || (fileLengthClosed != size))
throw new IOException("The channel size or file length does not match the truncate size. Channel: " + channelSize + " - Open File: " + fileLengthOpen + " - Closed File: " + fileLengthClosed + " - Truncate: " + size);
}
在极少数情况下,代码抛出IOException
<代码>频道大小=大小
和文件长度打开
=大小
但文件长度关闭
!=<代码>大小
为什么文件长度已关闭
!=<代码>大小?如何确保File.length()
匹配FileChannel.size()
?只要不强制刷新文件内容,刷新文件元数据就可以了。刷新文件内容将导致不必要的文件I/O
告诉我使用channelSize
或fileLengthOpen
或忽略问题的答案将不被接受。我有另一个类文件,它使用file.length()
来确定文件的长度。将channelSize
或fileLengthOpen
传递给另一个类需要将该值向上传递堆栈中的几个帧,然后向下传递几个帧。如果您建议我使用Files.size()
来解决此问题,请解释原因
我不确定这是否重要。我正在Linux上运行Java10。(是的,我知道Java 10很旧,但我一直坚持使用它,直到我能够实现升级到Java 11所需的功能。)
编辑:过去,文件的多线程更新会导致问题。出于这个原因,我创建了一个文件锁定机制,这样整个进程中只有一个线程可以独占地操作一个文件(或者多个线程可以读取该文件)。此外,传递给mytruncate()
的文件
对象是由调用线程创建的,并且仅由该线程使用。我可以保证进程中没有其他线程可以对磁盘上的文件或文件
对象进行操作
编辑:我将代码更改为调用
Files.size()
在channel.close()之前和之后channel.size()
,File.length()
和Files.size()
在channel
打开时报告正确的大小。就在channel.close()
之后,File.length()
和Files.size()
很少是原始的较长文件长度,而不是截断的较短长度。旋转等待fileLengthClosed
正确。这是代码
while (true)
{
fileLengthClosed = file.length();
if (fileLengthClosed == size)
break;
Thread.sleep(1);
}
我已经运行这段代码3周了,没有出现任何问题。一个问题是,如果文件长度被修改或file.length()
从不更新,则没有超时代码
此解决方案无法回答为什么File.length()
首先是不正确的。另外,调用Thread.sleep()
表明我正在等待其他操作完成,我真的应该强制该操作完成或阻止该操作。我不知道如何强制或阻止该操作。为什么不使用Files.size()
?文件
类应该已经被允许和平死亡。您是否尝试过查看文件.size()
是否存在此问题?众所周知,Windows在文件打开时不会更新文件元数据。我的代码库中大约有90个位置使用了文件.length()
。如果我能证明它解决了问题,我会将代码更改为Files.size()
。我更改了truncate()
以检查文件.size()
在关闭FileChannel
之前和之后的情况,我将看看会发生什么。。。重现此问题可能需要几天时间。不幸的是,此问题不会在Windows上重现。但是,这并不能说明什么,因为这个问题在Linux上并不经常出现。@realponsign我在使用Files.size()
后更新了这个问题Files.size()
与File.length()
具有相同的问题。