C/C++ 中的简单虚拟文件系统
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1361560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Simple Virtual Filesystem in C/C++
提问by Paolo Tedesco
I would like to implement a very simple Virtual Filesystem (VFS) which supports some basic file system operation like fwrite, fopen, fput, etc. The VFS is an abstraction layer on top of some concrete OS, e.g. Windows, Linux etc. Assume now, that the fopen interface looks something like this
我想实现一个非常简单的虚拟文件系统 (VFS),它支持一些基本的文件系统操作,如 fwrite、fopen、fput 等。 VFS 是一些具体操作系统(例如 Windows、Linux 等)之上的抽象层。现在假设, fopen 界面看起来像这样
FILE VFS_File_Open( const unsigned char* strFile, int flags );
Now I am wondering how I can make in the actual implementation of this interface the distinction about which filesystem I am talking to. Is there in C something that tells me on which OS the application is running so that I could do something like this:
现在我想知道如何在这个接口的实际实现中区分我正在谈论的文件系统。在 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
}
EDIT:
编辑:
Now I am wondering if anyone knows where I can find the system calls for file operations for Windows? It is easy to find them for Linux but I struggled to find something similar for windows, e.g. I would be interested in the system calls to open a file, write a file, etc.
现在我想知道是否有人知道我在哪里可以找到 Windows 文件操作的系统调用?在 Linux 上很容易找到它们,但我很难为 Windows 找到类似的东西,例如,我会对打开文件、写入文件等的系统调用感兴趣。
On another note: The C stdio.h offers a number of stand IO operations like
另请注意:C stdio.h 提供了许多标准 IO 操作,例如
FILE * fopen (const char *filename, const char *opentype)
In other words, I do not have to reimplement the fopen routine in my VFS as the Gnu C library takes care about what OS it is dealing with, is that right? I just have to implement functionality that is not supported by stdio library, e.g. creating directories, which differ from filesystem to filesystem?
换句话说,我不必在 VFS 中重新实现 fopen 例程,因为 Gnu C 库会关心它正在处理的操作系统,对吗?我只需要实现 stdio 库不支持的功能,例如创建不同文件系统的目录?
Thanks
谢谢
回答by Paolo Tedesco
Maybe the simplest/cleanest implementation would be to create two separate libraries, one for windows and one for linux, without littering your code with cascaded if
and switch
statements. The libraries would implement the same functions, defined in a common header.
也许最简单/最干净的实现是创建两个单独的库,一个用于 Windows,一个用于 linux,而不会用级联if
和switch
语句乱扔代码。这些库将实现相同的功能,在公共头文件中定义。
Also, remember that the code inside your check OS == something
would be compiled and linked on all systems, so e.g. the library compiled on linux should be able to resolve the windows system calls...
另外,请记住检查中的代码OS == something
将在所有系统上编译和链接,因此例如在 linux 上编译的库应该能够解析 windows 系统调用...
I think separating things (different OS, different cpp files) is the simplest solution.
我认为分离事物(不同的操作系统,不同的 cpp 文件)是最简单的解决方案。
EDIT:
编辑:
If you are using C++, why not just relying on streams? The standard library already provides the functionality you are trying to implement and is available on all platforms.
Otherwise, here's a link to Windows File Management Functions.
如果您使用 C++,为什么不只依赖流?标准库已经提供了您尝试实现的功能,并且可以在所有平台上使用。
否则,这里有一个指向Windows 文件管理功能的链接。
SECOND EDIT:
第二次编辑:
If you want a cross-platform file system library, supporting among other things directory creation, you could check the boost filesystem library.
如果你想要一个跨平台的文件系统库,支持目录创建,你可以查看boost 文件系统库。
回答by Nick Dandoulakis
I don't think you can compile a module for different OSes, the way you want.
我不认为你可以按照你想要的方式为不同的操作系统编译一个模块。
// 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
}
回答by MSalters
Actually implemented this, so from experience here:
实际实现了这一点,所以从这里的经验来看:
The first thing to do is use classes. There is no fopen()
equivalent. If there are flags, they're going to be an enum. Filenames are wchar_t nowadays.
首先要做的是使用类。没有fopen()
等价物。如果有标志,它们将是一个枚举。现在文件名是 wchar_t 。
The second thing to do is factor out the OS-dependent parts of your file class. They should be in separate methods. You move these to a seperate file. For every OS you have, there will be a different file implementing the same methods. When you link your app, you know the target architecture and you can pick the correct versions.
要做的第二件事是分解出文件类中与操作系统相关的部分。它们应该在不同的方法中。您将这些移动到一个单独的文件。对于您拥有的每个操作系统,都会有一个不同的文件实现相同的方法。当你链接你的应用程序时,你知道目标架构,你可以选择正确的版本。
回答by Martin B
If you're looking for a way to abstract yourself from the properties of the filesystem you're using (path separators etc.), and if you're happy with a C++-only solution, take a look at Boost.Filesystem.
如果您正在寻找一种方法来从您正在使用的文件系统的属性(路径分隔符等)中抽象出自己,并且如果您对仅 C++ 的解决方案感到满意,请查看Boost.Filesystem。
Paths can be specified in the portable generic path format(basically POSIX format) and are automatically converted to the native format:
路径可以用可移植的通用路径格式(基本上是 POSIX 格式)指定,并自动转换为原生格式:
path my_path( "some_dir/file.txt" );
Elements can be concatenated onto the path using the /
operator, and the result can then directly be used to open a file:
元素可以使用/
运算符连接到路径上,然后结果可以直接用于打开文件:
ifstream file1( my_path / "foo/bar" );
What's more, this functionality is part of Technical Report 2, meaning that it will likely make its way into the standard library.
更重要的是,此功能是技术报告 2 的一部分,这意味着它很可能会进入标准库。
回答by Martin v. L?wis
Standard C has no such feature. Notice that the notion of "concrete OS" is also a bit vague: are Windows XP and Windows Vista the same "concrete OS", or different ones? Are CentOS and Ubuntu the same OS, or different ones?
标准 C 没有这样的功能。请注意,“具体操作系统”的概念也有点模糊:Windows XP 和 Windows Vista 是相同的“具体操作系统”还是不同的?CentOS 和 Ubuntu 是同一个操作系统还是不同的操作系统?
Apparently, you are only looking for API differences, so in most cases, you can probably ignore version differences and distribution differences (although both Windows and Linux grow new system calls from time to time). In this case, it is best to preprocessor conditional compilation - since the code making Linux-specific calls won't even compile on Windows.
显然,您只是在寻找 API 差异,因此在大多数情况下,您可能可以忽略版本差异和发行版差异(尽管 Windows 和 Linux 都会不时增加新的系统调用)。在这种情况下,最好预处理条件编译 - 因为进行特定于 Linux 的调用的代码甚至无法在 Windows 上编译。
Traditionally, the system compilers have various macros predefined. Here are a few such macros, on respective systems: _WIN32
, __linux
, __linux__
, __AIX__
, __hpux
, ... If you need to identify a specific system, you should ask again on SO.
传统上,系统编译器预定义了各种宏。这里有一些这样的宏,在各自的系统上:_WIN32
, __linux
, __linux__
, __AIX__
, __hpux
, ... 如果你需要识别一个特定的系统,你应该在 SO 上再次询问。