Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中刷新FileOutputStream:操作系统本身是否可以缓存(推迟)实际写入,并且File.size()返回;“错误”;价值_Java_File_Size_Outputstream_Flush - Fatal编程技术网

在Java中刷新FileOutputStream:操作系统本身是否可以缓存(推迟)实际写入,并且File.size()返回;“错误”;价值

在Java中刷新FileOutputStream:操作系统本身是否可以缓存(推迟)实际写入,并且File.size()返回;“错误”;价值,java,file,size,outputstream,flush,Java,File,Size,Outputstream,Flush,首先,我为文字墙道歉 我正在将数据块写入文件(使用FileOutputStream);我不时地刷新并检查文件的长度(file.length()),以查看是否已达到某个阈值。这些日志文件需要可供进一步请求时使用 代码在一个生产环境中,是一个精心设计的日志系统的一部分;因此,我为缺少代码而道歉——这不仅不切实际,而且根本不可能在这里发布。然而,上面的琐碎描述却恰到好处 我担心的是,虽然在99.9%的情况下,一切都按预期进行(自系统使用以来,可能有上万个日志文件被审查),但有时我仍然会收到比我的阈值高

首先,我为文字墙道歉

我正在将数据块写入文件(使用FileOutputStream);我不时地刷新并检查文件的长度(file.length()),以查看是否已达到某个阈值。这些日志文件需要可供进一步请求时使用

代码在一个生产环境中,是一个精心设计的日志系统的一部分;因此,我为缺少代码而道歉——这不仅不切实际,而且根本不可能在这里发布。然而,上面的琐碎描述却恰到好处

我担心的是,虽然在99.9%的情况下,一切都按预期进行(自系统使用以来,可能有上万个日志文件被审查),但有时我仍然会收到比我的阈值高出很多倍的文件—我怀疑没有正确报告文件的大小。在写入任何大数据块之前,我会刷新并检查文件大小,我确信这会强制将数据发送到磁盘

(不会引发任何安全异常,文件权限没有问题,并且在代码的其他地方没有使用……换句话说,无法说明为什么会错误地报告大小。我不认为防病毒锁会影响报告的文件大小。数据块本身不会影响行为,与其他文件相比,它们非常小阈值大小。当然,复制此问题几乎是不可能的,唯一的方法是……记录更多调试信息。)

查看Java文档(),他们似乎建议操作系统可能会推迟实际的磁盘写入,这可以解释为什么有时我会得到所描述的行为。如果有人能解释一下我是否正确地解释了这段话,我将不胜感激:

Flushes this output stream and forces any buffered output bytes to be written out. 
The   general contract of flush is that calling it is an indication that, if any bytes 
previously written have been buffered by the implementation of the output stream, such     
bytes should immediately be written to their intended destination.

If the intended destination of this stream is an abstraction provided by the underlying 
operating system, for example a file, then flushing the stream guarantees only that   
bytes previously written to the stream are passed to the operating system for writing;  
it does not guarantee that they are actually written to a physical device such as a 
disk drive.
到目前为止,Vista用户似乎有这个问题;不能说这是否是一个硬性规定


在“大方案”中还有什么可以缓存或缓冲数据的吗?

操作系统可能会自己写缓冲区,而您引用的javadocs中的文本指出,通常OutputStream对象不会尝试对操作系统缓冲做任何事

具体而言,Windows执行内部写入缓冲。这是来自:

通常,WriteFile和WriteFilex函数将数据写入内部缓冲区,操作系统会定期将数据写入磁盘或通信管道


因此,在您的情况下,文件大小的更新可能会延迟。

在关闭文件之前,平台可能不会更新文件中的元数据。例如,Windows会这样做。因此,无论最终写入是否以物理方式进行,
file.length()
在文件打开时仍然可以返回意外值。

谢谢你,EJP。在你的答案和Pvgoran的答案之间进行了艰难的选择,但我觉得虽然他的答案与我表述主题的方式完美匹配,但你的答案在我的使用上下文中提供了一些额外的内容。非常感谢。a
sync()
文件描述符的
强制更新磁盘上的元数据,因此也有
长度
属性?这似乎是Linux的情况,但我找不到Windows或OS X的任何答案。@elderder来自:“…传递true表示必须写入对文件内容和元数据的更新,这通常需要至少再执行一次I/O操作。此参数是否实际有效取决于基础操作系统,因此未指定。“谢谢你,这给了我一个探索的方向。谢谢你,Pvgoran,谢谢你的输入(特别是额外的细节)。出于我对EJP答案的评论中提到的原因,我选择了他;我认为我面临的行为与他所提到的相当(“缓存”有时高达1GB!)实际上,EJP的答案在File.length()行为方面提供了更多信息。