我在考虑把这个问题改成我的情况。然后我决定我的情况需要自己的问题并希望得到答案。在调用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);
}
Run Code Online (Sandbox Code Playgroud)
在极少数情况下,代码会抛出IOException. channelSize==size和fileLengthOpen==size但是fileLengthClosed!= size。
为什么fileLengthClosed!= size?我如何确保File.length()匹配FileChannel.size()?只要不强制刷新文件的内容,刷新文件的元数据就可以了。刷新文件的内容会导致不必要的文件 I/O。
不接受告诉我使用channelSize或fileLengthOpen忽略问题的答案。我有另一个File.length()用于确定文件长度的类文件。将channelSize或传递fileLengthOpen给其他类需要将值向上传递几帧,然后再向下传递几帧。如果您建议我用它Files.size()来解决问题,请解释原因。
我不确定这是否重要。我在 Linux 上运行 Java 10。(是的,我知道 Java 10 很旧,但我一直坚持使用它,直到我可以实现升级到 Java 11 的必要功能。)
编辑:过去,文件的多线程更新会导致问题。为此,我创建了文件锁定机制,以便整个进程中只有 1 个线程可以独占操作一个文件(或多个线程可以读取该文件)。此外,File传递给 my的对象truncate()是由调用线程创建的,并且仅供该线程使用。我可以保证进程中没有其他线程可以对磁盘上的文件或File对象进行操作。
编辑:我将代码更改为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);
}
Run Code Online (Sandbox Code Playgroud)
我已经运行这段代码 3 周了,没有出现任何问题。一个问题是,如果文件长度被修改或file.length()从不更新,则没有超时代码。
File.length()该解决方案一开始就没有回答为什么是错误的。另外,调用Thread.sleep()表明我确实正在等待其他一些操作完成,并且我确实应该强制该操作完成或阻止该操作。我不知道如何强制或阻止该操作。
| 归档时间: |
|
| 查看次数: |
251 次 |
| 最近记录: |