Java FileChannel.size()vs File.length() - 在FileChannel.truncate()之后

问题描述 投票:4回答:1

我在考虑将this question改成我的情况。然后我决定我的情况需要自己的问题并希望得到答案。在调用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);
}

在极少数情况下,代码抛出IOExceptionchannelSize == sizefileLengthOpen == size但是fileLengthClosed!= size

为什么fileLengthClosed!= size?我怎样才能确保File.length()FileChannel.size()相匹配?只要不强制刷新文件的内容,刷新文件的元数据就没问题。刷新文件的内容会导致不需要的文件I / O.

答案告诉我使用channelSizefileLengthOpen或忽略该问题将不被接受。我有另一个类文件,使用File.length()来确定文件的长度。将channelSizefileLengthOpen传递给另一个类需要将值向上传递几帧,然后向下传递几帧。如果您建议我使用Files.size()来解决问题,请解释原因。

我不确定这是否重要。我在Linux上运行Java 10。 (是的,我知道Java 10已经老了,但是我坚持使用它,直到我可以实现升级到Java 11的必要功能。)

编辑:过去,文件的多线程更新导致了问题。出于这个原因,我创建了一个文件锁定机制,以便整个进程中只有一个线程可以独占于一个文件(或多个线程可以读取该文件)。此外,传递给我的Filetruncate()对象是由调用线程创建的,仅由该线程使用。我可以保证进程中没有其他线程可以对磁盘上的文件或File对象进行操作。

编辑:我更改了代码,在Files.size()之前和之后调用channel.close()。当channel.size()开放时,File.length()Files.size()channel报告正确的大小。在channel.close()之后,File.length()Files.size()是罕见的情况下原始较长的文件长度而不是截短的较短长度。

java filesize
1个回答
0
投票

旋转等待fileLengthClosed是正确的。这是代码。

while (true)
{
   fileLengthClosed = file.length();

   if (fileLengthClosed == size)
      break;

   Thread.sleep(1);
}

我已运行此代码3周,并且没有任何问题。一个问题是,如果文件长度被修改或file.length()永远不会更新,则没有超时代码。

这个解决方案没有回答为什么File.length()首先是不正确的。此外,调用Thread.sleep()表明我真的在等待其他一些操作完成,我真的应该强制该操作完成或阻止该操作。我不确定如何强制或阻止该操作。

© www.soinside.com 2019 - 2024. All rights reserved.