测试缓冲区是不是已在 R 中刷新
Posted
技术标签:
【中文标题】测试缓冲区是不是已在 R 中刷新【英文标题】:Testing whether buffers have been flushed in R测试缓冲区是否已在 R 中刷新 【发布时间】:2011-08-08 21:56:09 【问题描述】:我有一些非常大的文件要处理,我使用几个不同的 I/O 函数来访问它们。最常见的是bigmemory
包。
在写入文件时,我已经学会了刷新输出缓冲区的艰难方法,否则所有关于数据是否已保存的赌注都将落空。但是,这可能会导致在bigmemory
完成它的工作(很多分钟)时等待一些非常长的时间。我不知道为什么会发生这种情况——它并不总是发生,也不容易重现。
是否有某种方法可以确定 I/O 缓冲区是否已在 R 中刷新,尤其是对于 bigmemory
?如果操作系统很重要,请随意以这种方式限制答案。
如果可以将答案推广到 bigmemory
之外,那就太好了,因为我有时会依赖其他内存映射函数或 I/O 流。
如果没有好的解决方案来检查缓冲区是否已被刷新,是否存在可以假设缓冲区已被刷新的情况? IE。除了使用flush()
。
更新:我应该澄清一下,这些都是二进制连接。 @RichieCotton 注意到 isIncomplete()
,尽管帮助文档只提到了文本连接。不清楚这是否可用于二进制连接。
【问题讨论】:
不确定是否与bigmemory
一起使用,但isIncomplete
适用于常规连接。
谢谢!关于连接的非常有限的帮助信息只提到 isIncomplete 适用于文本连接的输出。你在二进制连接上遇到过运气吗?
【参考方案1】:
isIncomplete() 处理二进制文件是否更有说服力?
# R process 1
zz <- file("~/test", "wb")
writeBin(c(1:100000),con=zz)
close(zz)
# R process 2
zz2 <- file("~/test", "rb")
inpp <- readBin(con=zz2, integer(), 10000)
while(isIncomplete(con2)) Sys.sleep(1); inpp <- c(inpp, readBin(zz2),integer(), 10000)
close(zz2)
(根据帮助(连接)文件修改。)
【讨论】:
感谢您对此进行测试。但是,除非我误读了,否则您的示例仅在输入缓冲区的情况下使用它。我不太清楚它是否适用于输出缓冲区。我对输出缓冲不够熟悉,无法确定我们是否可以以同样的方式对其进行测试。我只是不愿意超越文档-如果它的行为是随机的,而不是确定性的,那么我冒着一堆损坏的数据的风险。我一直在这条路上,所以我很谨慎。 :) 经过进一步测试,我认为isIncomplete()
不适用于bigmemory
对象:似乎对象是某种指针,而不是连接。 :(
感谢您的建议和示例。事实证明,在这种情况下,缓冲区是在 R 之外处理的。【参考方案2】:
我会提出我自己的答案,但我欢迎任何更清楚的内容。
据我目前所见,各种连接功能,例如file
、open
、close
、flush
、isOpen
和 isIncomplete
(以及其他)基于特定的连接类型,例如文件、管道、URL 和其他一些东西。
相比之下,bigmemory
有自己的连接类型,而 bigmemory 对象是一个 S4 对象,带有一个用于操作系统缓冲区的内存地址的插槽。一旦放置在那里,操作系统就负责刷新这些缓冲区。由于这是操作系统的责任,因此获取有关“脏”缓冲区的信息需要与操作系统交互,而不是与 R。
因此,bigmemory
的答案是“否”,因为数据存储在内核缓冲区中,尽管对于通过 STDIO 处理的其他连接(即存储在“用户空间”中)可能是“是”。
有关操作系统/内核方面的更多信息,请参阅this question on SO;我正在研究几个产生缓冲区刷新好奇心的程序(不仅仅是 R + bigmemory),该线程帮助我了解了内核方面的事情。
【讨论】:
以上是关于测试缓冲区是不是已在 R 中刷新的主要内容,如果未能解决你的问题,请参考以下文章