【问题标题】:Determine length of compiled binary确定已编译二进制文件的长度
【发布时间】:2013-06-29 05:54:34
【问题描述】:

我正在尝试访问程序的已编译二进制文件的长度,但它返回 -1。有人可以指出我在正确的轨道上吗?我不确定为什么下面的代码没有产生正确的结果。

std::fstream file(argv[0], std::ios::binary | std::ios::ate);
std::cout << file.tellg() << "\n";

【问题讨论】:

标签: c++


【解决方案1】:

只需将std::ios::in 添加到打开模式标志就可以了。 (构造函数未能打开文件。根据标准,您必须指定inoutapp 之一。)

将流类型更改为 std::istream 也可以,但生成的二进制文件大 8 个字节。

【讨论】:

  • 啊,非常感谢。更改流类型实际上对我来说破坏了它,但是使用 ios::in 规范它工作得很好。奇怪的是 istream 会增加这么多文件大小。
【解决方案2】:

-1 结果表示打开失败。您应该始终对此进行测试:

if (std::fstream file(argv[0], std::ios::binary | std::ios::ate)) {
    std::cout << file.tellg() << "\n";
} else {
    // Report error.
}

第二个问题是,如果你只是想得到它的长度,你应该打开它以只读方式(这可能是打开失败的原因):

std::ifstream file(argv[0], …);

第三个问题是argv[0] 不能保证包含有效的可执行文件名。这只是一个广泛持有的假设。你通常会侥幸逃脱,但你应该牢记这一点。

【讨论】:

  • 啊,谢谢。我将添加检查以确保它读取可执行文件,但没有意识到这不是保证。
  • 与这个问题相关的是,即使argv[0] 包含一个有意义的文件名,它在传递给ifstream 时仍可能无法正确解析。例如,如果您的程序 foobar 在路径上找到并且不在当前目录中,则argv[0] 将包含foobar,这将无法打开,因为当前目录中没有任何名为 foobar 的内容。
  • … 或者如果用户执行程序时使用的权限与 shell 用来查找它的权限不同,例如 sudo someuser。有无数的事情会出错。 C++ 甚至根本不保证机器上有一个文件系统。当然,即使有文件系统,程序也可能不会存储在文件中。
  • @user2142343:是的,但是如果您接受我的建议使用std::ifstream,那么您基本上已经规定您只想阅读。即使您解决了这个问题,您也可能不会被允许写入正在运行的程序的二进制文件。你当然不能在 Windows 中; Linux 限制较少,但您仍可能会遇到问题。
  • @user2142343:如果您提供一些背景信息,您可能会从 SO 那里得到更有帮助的回复。为什么要这样做?你想达到什么目的?这将减少绊倒the XY problem 的风险。
猜你喜欢
  • 1970-01-01
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多