C/C++中的简单虚拟文件系统

9

我希望实现一个非常简单的虚拟文件系统(VFS),支持一些基本的文件系统操作,比如fwrite、fopen、fput等。VFS是在某些具体操作系统(例如Windows、Linux等)之上的抽象层。现在假设,fopen接口长这个样子

FILE VFS_File_Open( const unsigned char* strFile, int flags );

现在我想知道如何在实际实现这个接口时区分我正在讨论哪个文件系统。在C语言中,是否有一些东西可以告诉我应用程序运行在哪个操作系统上,以便我可以像这样做:

FILE VFS_File_Open( const unsigned char strFile, int flags )
{
int OS = getOSID();

if (0S == 1)
  //implement here the system calls required to open a file on a WIN OS
else if (OS == 2)
  //implement here the system calls required to open a file on a Linux OS
etc  
}

编辑:

现在我想知道是否有人知道在Windows中可以找到文件操作的系统调用? 在Linux中很容易找到它们,但我很难找到类似于Windows的内容,例如,我对打开文件、写文件等系统调用感兴趣。

另外一件事:C stdio.h提供了许多标准IO操作,如

FILE * fopen (const char *filename, const char *opentype)

换句话说,我不需要在我的VFS中重新实现fopen例程,因为Gnu C库会处理它正在处理的操作系统,是这样吗?我只需要实现stdio库不支持的功能,例如创建目录,这些功能因文件系统而异?谢谢。

你的问题不太清楚,不确定你是否需要一个虚拟文件系统切换来处理多个不同的文件系统(如EXT2、FAT),还是想要在操作系统之间进行切换。 - user6754053
6个回答

13

也许最简单/最清晰的实现方式是创建两个独立的库,一个为Windows系统,另一个为Linux系统,而不是在代码中嵌套使用ifswitch语句。这些库将实现相同的函数,在共同的头文件中定义。

此外,请记住您的检查OS == something内的代码将在所有系统上进行编译和链接,因此例如,在Linux上编译的库应该能够解析Windows系统调用...

我认为分离事物(不同的操作系统,不同的cpp文件)是最简单的解决方案。

编辑

如果您使用的是C ++,为什么不依赖于streams?标准库已经提供了您正在尝试实现的功能,并且可在所有平台上使用。
否则,这里有一个链接到Windows文件管理函数

第二次编辑

如果您需要跨平台的文件系统库,支持目录创建等功能,则可以查看boost文件系统库


我喜欢这个想法,使用一个共同的头文件和不同的库来适配不同的操作系统。实质上,我只需要按照Nick D.建议的方式来做,根据操作系统包含相应的库即可。 - Sam
或者说,当您构建Windows解决方案时,您会链接Windows库等。在这两种情况下都包含了公共头文件:编译将是相同的,在链接阶段将考虑特定于平台的内容。 - Paolo Tedesco

7
我认为你无法按照你想要的方式为不同的操作系统编译模块。
// Make the distinction at compile time,

FILE VFS_File_Open( const unsigned char strFile, int flags )
{
#ifdef _WINDOWS
    //implement here the system calls required to open a file on a WIN OS
#endif
#ifdef _LINUX
    //implement here the system calls required to open a file on a Linux OS
#endif
    etc
}

3
当然,如果你想把所有东西都放在一个文件中,这个区分必须在编译时进行 (+1)。我仍然认为分离的做法更好。 - Paolo Tedesco
非常感谢。这也是我考虑过的一种方法!因此,与orsogufo的答案结合起来应该会给我一个良好的开端! - Sam
2
是的,我同意。实际上这是设计跨平台项目的常见模式。 - Nick Dandoulakis

6

OP询问如何实现虚拟文件系统,而不是寻求库的建议。 - Ian Young

1

实际上,我已经实现了这个功能,所以从我的经验来看:

第一件事是使用类。没有fopen()等效函数。如果有标志,它们将是枚举类型。文件名现在是wchar_t。

第二件事是将文件类的与操作系统相关的部分分离出来。它们应该在单独的方法中。您可以将它们移动到单独的文件中。对于每个操作系统,都会有一个不同的文件实现相同的方法。当您链接应用程序时,您知道目标架构,可以选择正确的版本。


0

标准C没有这个特性。注意,“具体的操作系统”这个概念也有点模糊:Windows XP和Windows Vista是同一“具体的操作系统”,还是不同的操作系统?CentOS和Ubuntu是同一个操作系统,还是不同的操作系统?

显然,您只在寻找API差异,因此在大多数情况下,您可以忽略版本差异和发行版差异(虽然Windows和Linux都会不时增加新的系统调用)。在这种情况下,最好使用预处理条件编译-因为调用Linux特定的代码在Windows上甚至无法编译。

传统上,系统编译器有各种宏预定义。以下是各自系统上的一些这样的宏:_WIN32__linux__linux____AIX____hpux等。如果您需要识别特定的系统,您应该再在SO上提问。


0

如果你正在寻找一种将自己与使用的文件系统属性(路径分隔符等)抽象化的方法,并且如果你对纯C++解决方案满意,请看看Boost.Filesystem

路径可以以便携通用路径格式(基本上是POSIX格式)指定,并且会自动转换为本地格式:

path my_path( "some_dir/file.txt" );

使用/运算符可以将元素连接到路径上,然后可以直接使用结果打开文件:

ifstream file1( my_path / "foo/bar" );

此外,这个功能是技术报告2的一部分,这意味着它很可能会被纳入标准库中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接