使用fstream输入二进制文件失败,但路径正确



当我搜索这个主题时,我发现了很多关于如何使用std::fstream正确访问二进制文件的示例。我提取了一个片段,它编译得很好(Visual Studio 2017(。但是,在运行时(此代码位于DLL中(,该文件似乎不会打开。我假设文件不必是*.bin或其他什么文件就可以工作。。。这是正确的吗?我想不出还有什么偏离轨道了。对缓冲区的解读可能是错误的——我甚至还不能理解这一部分。

std::fstream binaryFile;
binaryFile.open(cdgName, std::ios::binary);
if (binaryFile.good())
{
BYTE i[24];
while (binaryFile >> i)
{
//handle
}
binaryFile.close();
} else 
{
MessageBoxA(NULL, cdgName, "File Error!", MB_OK);
}

当我尝试此操作时,会显示MessageBox。仅供参考,该窗口包含文件路径(cdgName(,它是"C:UsersRickMusicAmerica - You Can Do Magic.cdg",这是一个有效的文件。我也试过.is_open()而不是.good()。我尝试了ifstream和使用::ios::in标志的变体——不知道我在做什么——这在运行时导致了错误。

标准库的流非常糟糕。他们没有做的一件更重要的事情是帮助您调试。

如果你这样做,那么除了失败之外,你还可以得到一条有用的错误消息。

考虑这个main.cpp:

#include <array>
#include <cerrno>
#include <cstdio>
#include <cstring>
#include <functional>
#include <memory>
#include <stdexcept>
#include <string>
#include <string_view>
using BYTE = char;
auto
read_my_file(std::string_view cdgName)
{
std::string name{cdgName}; // ensure that a null terminating byte is there
using file_ptr = std::unique_ptr<std::FILE, std::function<decltype(std::fclose)>>;
file_ptr f{std::fopen(name.c_str(), "r"), &std::fclose};
if (nullptr == f)
{
throw std::runtime_error{std::string{"fopen(): "} + std::strerror(errno)};
}
std::array<BYTE, 24u> out{};
auto count = std::fread(out.data(), sizeof(BYTE), out.size(), f.get());
if (0 != std::ferror(f.get()))
{
throw std::runtime_error{std::string{"fread(): "} + std::strerror(errno)};
}
if (count < out.size())
{
throw std::runtime_error{std::to_string(count)};
}
return out;
}
#include <cstdlib>
#include <iostream>
int main(int argc, char **argv)
try
{
if (argc <= 1)
{
return EXIT_FAILURE;
}
auto out = read_my_file(argv[1]);
std::cout << out.data() << std::endl;
return EXIT_SUCCESS;
}
catch (const std::runtime_error& e)
{
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}

g++ -std=c++17 main.cpp编译。然后考虑一些调用示例:

$ ./a.out

这是空的,但进程退出代码是1

$ ./a.out example.txt

->fopen(): No such file or directory

$ echo "foo" > example.txt && ./a.out example.txt

->4(文件中只有4个字节,而不是请求的24个(

$ echo "hello world this is an example" > example.txt && ./a.out example.txt

->hello world this is an e

好吧,这是一条快乐的道路,也是一条悲伤的道路。但假设你看到的是权限问题?

chmod 700 example.txt && sudo chown root:root example.txt && ./a.out example.txt

->fopen(): Permission denied

我不相信fstream能做那样的事。。。

最新更新