首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java FileChannel.size() vs File.length() -在FileChannel.truncate()之后

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

Stack Overflow用户
提问于 2019-04-07 15:17:42
回答 1查看 438关注 0票数 5

我在考虑把this question变成我的处境。然后我决定,我的情况需要自己的问题和希望的答案。在调用FileChannel.truncate()以缩小文件大小后,我调用FileChannel.size(),关闭FileChannel,然后调用File.length()。文件在整个操作过程中都存在。FileChannel.size()总是准确的。在很少的情况下,File.length()会在truncate()之前返回文件的大小。

下面是显示情况的代码。

代码语言:javascript
复制
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 == sizefileLengthClosed != size.

为什么fileLengthClosed != size?如何确保File.length()FileChannel.size()匹配?只要不强制刷新文件的内容,就可以刷新文件的元数据。刷新文件的内容将导致不必要的文件I/O。

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

我不知道这是否重要。我正在Linux上运行Java 10。(是的,我知道Java 10已经过时了,但是在我能够实现升级到Java 11所需的特性之前,我一直在使用它。)

编辑:在过去,多线程的文件更新造成了问题.因此,我创建了一个文件锁定机制,以便整个进程中只有一个线程可以独占地操作一个文件(或者多个线程可以读取该文件)。此外,传递给我的File对象是由调用线程创建的,并且仅由该线程使用。我可以保证进程中的任何其他线程都不能对磁盘上的文件或File对象进行操作。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-01 16:25:57

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

代码语言:javascript
复制
while (true)
{
   fileLengthClosed = file.length();

   if (fileLengthClosed == size)
      break;

   Thread.sleep(1);
}

我已经运行了3个星期的代码,没有任何问题。一个问题是,如果文件长度被修改,或者file.length()从未更新,那么就没有超时代码。

这个解决方案一开始并不回答为什么File.length()是不正确的。此外,调用Thread.sleep()意味着我真的在等待其他操作的完成,我真的应该强制该操作完成或阻止该操作。我不知道如何强制或阻止这一行动。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55560520

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档