在C程序中抽象文件系统的方法

4

我正在使用SDL编写程序,需要从文件系统中加载资源。 我希望程序内部的文件调用是跨平台的。我的初始想法是定义一个宏(我们称之为PTH),根据系统类型在预处理器中定义它,然后在程序中使用它进行文件调用。 例如:

SDL_LoadBMP(PTH("data","images","filename"));

这将简单地转化为与文件系统相关的内容。

如果宏是执行此操作的接受方式,那么这样的宏会是什么样子(如何检查正在使用哪个系统,在宏中连接字符串?)

如果不是,那么执行此操作的接受方式是什么?


你是在寻找与文件系统类型无关的解决方案(例如ext3、ReiserFS、btrfs),还是与平台无关的解决方案(例如Windows、Mac和Linux)? - Rafe Kettler
除非在从异类文件系统调用文件时存在我不知道的一些注意事项,否则我会说它是平台无关的。 - Scribble Master
一个宏应该可以在两个上工作,我认为,一个预处理器确定的斜杠交换函数也可以。那很丑陋,但显然不是不可能的,所以我宁愿两者都有解决方案。 - Scribble Master
@Scribble:它们是两种不同的语言。无论您预先假设了什么解决方案,可用的解决方案都会有很大的差异。请挑选其中一种。 - Lightness Races in Orbit
针对这两个问题,答案已经给出了相关的解决方案,因此我相信没有理由再进行选择了。不过还是感谢您的贡献。 - Scribble Master
你要写多语言源文件,那么你会面临非常多的工作量,我是说非常多。我建议你不要混合使用C和C++(还有Pascal、FORTRAN、COBOL、Lisp等等)。 - pmg
5个回答

5

Boost Filesystem模块 可能是您的最佳选择。它在路径上覆盖了“/”运算符,因此您可以执行以下操作...

ifstream file2( arg_path / "foo" / "bar" );

+1,如果您忽略“C”标签,这是一个很好的建议。 - Flexo
3
当我看到 C++ 标签时,我通常会这么做。 - Andrew White
我希望有一些在C中也能工作的东西(这就是为什么我想到了宏),但Blindy提醒我glib在C中很好用。 - Scribble Master

2

谢谢,我确实知道glib,但它跑到我的脑后了。虽然我更喜欢支持C ++。 - Scribble Master
glib在C++中得到支持,因此您可以使用它。但是,如果您不需要C支持,boost::filesystem确实更好用。 - bdonlan
+1 因为你的回答有帮助且涉及到 C 和 C++,但是 Andrew White 的回答更加详细并且对大多数编程人员(C++)更加相关,所以我必须选择他的回答作为最佳答案,抱歉。 - Scribble Master

1

没有必要将此作为宏。

一种常用的方法是抽象路径以使用正斜杠作为分隔符,因为这(几乎意外地!)与实际平台的大部分情况非常匹配。对于那些不适用的平台,您只需在文件系统实现层内进行转换即可。


文件系统实现层是什么意思? - Scribble Master

0

查看OS9 os.path.join(macpath)的Python实现

def join(s, *p):
  path = s
  for t in p:
    if (not s) or isabs(t):
        path = t
        continue
    if t[:1] == ':':
        t = t[1:]
    if ':' not in path:
        path = ':' + path
    if path[-1:] != ':':
        path = path + ':'
    path = path + t
  return path

我不熟悉在旧版 Mac 上使用 SDL 进行开发。在游戏资源方面,另一个选择是使用包文件格式,并直接将资源加载到内存中(例如一个 map < string,SDL_Surface >)

这样,您只需加载一个文件(甚至可以是 zip 文件,在加载时解压缩)


0

在您的程序启动代码中,我建议您简单地执行平台等效版本的 chdir(data_base_dir);,然后使用相对Unix风格路径,例如"images/filename"。最后一个不支持这种写法的系统是MacOS9,而现在已经完全失去了它的相关性。


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