std::ofstream and system touch

5

在分析我的C++程序时,我发现当创建一堆文件时,调用std::ofstream()的时间比使用系统命令“touch”要少得多。

所以现在我想知道,在Linux上,std::ofstream映射到了哪个操作系统函数。

您知道std::ofstream()调用哪个函数来创建文件吗?

谢谢。


1
你是从命令行还是在程序内部作为函数调用 system("touch ..."); 发出 system "touch" 命令的? - hmjd
1
你如何比较C++函数(std::ofstream构造函数)与可执行文件(/bin/touch)的性能? - bobah
是的,我使用system()或者更好的方式:sprintf(temp, "touch %s", qPrintable(fileName))。但是根据回答,我现在明白了为什么我会有这样的开销。 - rmbianchi
3个回答

7
如果你正在执行system("touch filename");,那么这是误导性的、缓慢的(还有安全风险等等)。它并不直接调用系统,而是生成一个shell,然后在其中运行程序(在这种情况下是touch)。 打开一个流将使用某种实际的系统调用,可以直接访问文件系统。在Linux上可能会使用http://linux.die.net/man/2/open。 尝试在终端中运行strace touch以查找它所做的系统调用。你可能可以通过创建一个简单的c++程序来做同样的事情,只需打开一个文件。或者如果你正在使用开源实现(gcc),你可以检查源代码。

有点跑题,但这可能会帮助像我一样的其他人。我想从Mac应用程序中创建一个文件。system("touch filename")完成了任务,但它在磁盘根目录下创建了文件。为什么?我以为它会优先选择相对路径并在同一路径中创建文件...谢谢! - StinkyCat
@StinkyCat 你有点误解了重点,那就是 system() 是邪恶的,请不要使用它! 但恰好今天我正在尝试测试进程返回值,并遇到了类似的问题!在某些平台上,它可以找到本地程序,而在某些平台上则无法找到。 system 启动一个新的 shell,我猜想新的 shell 可能不会在与程序运行相同的目录中启动,尽管在 Linux 上似乎是这样的。无论如何,posix 标准表示它将以“实现定义的方式”执行。 - BoBTFish
1
是的,我从你的回答中明白了 :) 但我只是在做一个小测试,突然间它变成了一个大问题,让我无法放手。不过你已经解释得很清楚了,谢谢! - StinkyCat
实际上,我刚在Linux、Solaris和AIX上测试了system("pwd")命令,它们都给了我同样的起始目录(好吧,Solaris展开了一个软链接)。所以简而言之,我不知道。 - BoBTFish

4

你还应该考虑touch作为一个二进制文件的执行开销。我认为性能提升主要是因为在测量ofstream时,有一个持久的二进制文件存在于内存中。


好的观点,我相信执行touch命令时会创建一个操作系统进程。 - 01100110

1

想一下system()。它将fork/exec一个shell,该shell将从磁盘加载touch二进制文件、共享库等,执行它,清理进程并返回。

如果您只是使用touch创建不存在的文件,那么它大多相当于std::ofstream.open(),它将执行一些函数调用,并最终解析为系统调用open(),最终调用close()。速度更快。但是,如果您真的要模拟touch的功能,则会更加复杂。例如,如果文件已经存在,则仅更改时间戳等,需要涉及更多内容。

无论您的实际用途如何,在C++中编写代码都比通过system()运行外部程序更快。


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