2015-06-11 26 views
4

它经常会注意到,如果已经有方法创建“虚拟FILE”并为缓冲区满了,输入请求,关闭,冲洗等事件附加必要的回调,我将能够优雅地解决C中的实际问题。然后应该可以使用大部分的功能,例如, fprintf不变。 有没有一个框架可以做到这一点?如果不是,至少在某些平台上,适度的努力是否可行?虚拟化C的FILE *接口有多大的可行性?

可能的应用是:

  • 写入或从存储器的动态或静态区域读取。
  • 并行写入多个文件。
  • 从线程或协同例程中读取数据。
  • 将过滤器应用于其他(虚拟或实际)FILE
  • 支持间接文件格式(如#include)。
  • C预处理器(?)。

我不是在一个框架不太感兴趣的特定情况下的解决方案,让你滚你自己FILE。我也不是在寻找一个虚拟文件系统,而是我可以传递给CRT的虚拟FILE*

令我失望的是,我从未见过这样的事情;就我所见,C11认为FILE完全取决于语言实现者,如果希望将语言(+库)规范保持为小而悲伤,如果将其与Java I/O流进行比较,这可能是合理的。我觉得虚拟FILE必须可以用C运行时的任何(完全)开源实现,但我想可能有大量的细节使它比看起来更复杂,如果它已经完成了,重复这些努力将是一件耻辱。最好不要修改CRT代码。如果没有开源代码,人们可能会对所提供的功能进行逆向工程,但是我担心,除非承诺使用一组接口,否则结果将太脆弱,无法修改不支持的功能。我想,任何一个可以编写设备驱动程序的系统都可以创建一个虚拟设备,但我怀疑是不必要的低层次,需要编写特权代码。

我不得不承认,虽然我的代码可以从虚拟FILE中受益,但我目前没有这方面的要求;尽管如此,这是我经常想到的事情,而且我想其他人可能会感兴趣。

这有些类似于a-reader-interface-that-consumes-files-and-char-in-c,但是那里的提问者不希望返回虚拟的FILE;但是,答案是fmemopen,确实如此。

+0

你看过[libfuse](http://fuse.sourceforge.net/)吗?它允许你通过回调实现你自定义的文件系统(ioctl,read,stat,write,...) – mpromonet

+0

@mpromonet:不,我不熟悉libfuse,但是你的描述听起来很有希望......但是当我看起来我看到它听起来有点不同:我想要一个虚拟的(C)'FILE',我可以传递给例如'fprintf',而不是虚拟文件(在存储介质上)。但我认为libfuse可能会使用相关技术。 – PJTraill

+0

C是*旨在*被设计为没有I/O。所有的I/O都藏在图书馆里。这使得C便携。 C中有什么文件?可能是一个字节数组;但也许是可以寻求的。语义可能会蔓延,但仅限于语义层面。 – wildplasser

回答

5

没有用于创建虚拟FILE *的标准C接口,但GNU和BSD标准库都包含一个。在linux(glibc)上,你可以使用fopencookie;在大多数* BSD系统上,funopen(包括Mac OS X)。(见注1)

这两个接口是相似的,但在一些细节上略有不同。但是,将为一个接口编写的代码适用于另一个接口通常非常简单。

这些不是完整的虚拟化。他们将FILE*与四个回调和void*上下文关联(fopencookie中的“cookie”)。回调是read,write,seekclose;对于flushtell操作没有回调。尽管如此,这对于许多简单的FILE*适配器来说已经足够了。

举个简单的例子,看Write simultaneousely to two streams的两个答案。


注:

  1. funopen从 “功能开放” 衍生,而不是从 “文件未打开”。
+0

有趣。谢谢! –

+0

非常感谢,'fopencookie'听起来像我的意思; 'funopen'链接超时(可能是我的VPN)。我会仔细观察一下并给它一些时间,但我怀疑我会接受这个答案。这听起来像是属于标准C11 +库的东西! – PJTraill

+1

@PJTraill:如果您的VPN更喜欢,可以为man funopen添加一个apple.com链接。国际海事组织,如果它被添加到C或甚至是Posix,接口将需要更完整。 – rici