【问题标题】:Simple Virtual Filesystem in C/C++C/C++ 中的简单虚拟文件系统
【发布时间】:2010-11-24 14:19:24
【问题描述】:

我想实现一个非常简单的虚拟文件系统(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)进行虚拟文件系统切换,或者是否要在操作系统之间切换。

标签: c++ filesystems


【解决方案1】:

也许最简单/最干净的实现是创建两个独立的库,一个用于 Windows,一个用于 linux,而不会在代码中使用级联的 ifswitch 语句。这些库将实现相同的功能,定义在一个公共头文件中。

另外,请记住,检查 OS == something 中的代码将在所有系统上编译和链接,例如在linux上编译的库应该可以解析windows系统调用...

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

编辑

如果您使用 C++,为什么不只依赖 streams?标准库已经提供了您尝试实现的功能,并且适用于所有平台。
否则,这里是Windows File Management Functions 的链接。

第二次编辑

如果你想要一个跨平台的文件系统库,支持目录创建,你可以查看boost filesystem library

【讨论】:

  • 我喜欢通用头文件和用于不同操作系统的不同库的想法。本质上,我只需要按照 Nick D. 的建议去做,并根据操作系统包含相应的库。
  • 或者更确切地说,当您构建 Windows 解决方案时,您链接 Windows 库等等。您在两种情况下都包含公共标头:编译将相同,在链接阶段将考虑特定于平台的内容。
【解决方案2】:

我不认为你可以按照你想要的方式为不同的操作系统编译一个模块。

// 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
}

【讨论】:

  • 当然,如果你想把所有东西都保存在一个文件中,那么必须在编译时进行区分(+1)。我仍然认为分离的东西更好。
  • 非常感谢。这也是我想到的一种方法!所以与 orsogufo 答案的组合应该给我一个好的开始!
  • 是的,我同意。实际上,这是设计跨平台项目的常见模式
【解决方案3】:

你可以试试PhysicsFS库。

【讨论】:

  • OP 是在询问如何实现虚拟文件系统,而不是询问有关库的建议。
【解决方案4】:

实际上是这样实现的,所以从这里的经验来看:

首先要做的是使用类。没有 fopen() 等价物。如果有标志,它们将是一个枚举。现在的文件名是 wchar_t。

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

【讨论】:

    【解决方案5】:

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

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

    传统上,系统编译器预定义了各种宏。这里有一些这样的宏,在各自的系统上:_WIN32__linux__linux____AIX____hpux,...如果你需要识别一个特定的系统,你应该再问一次。

    【讨论】:

      【解决方案6】:

      如果您正在寻找一种方法来从您正在使用的文件系统的属性(路径分隔符等)中抽象出自己,并且如果您对纯 C++ 解决方案感到满意,请查看 @987654321 @。

      路径可以以可移植的通用路径格式(基本上是 POSIX 格式)指定并自动转换为原生格式:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-28
        • 1970-01-01
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多