将整个 std::ifstream 读入堆中

3

我无法弄清楚为什么这不起作用。据我所知,它似乎没有读取整个图像文件...虽然我无法确定。我基本上有一些原始图像,希望将其读入堆。

unsigned char* ReadImageFromFile(const char* FILENAME, unsigned int SIZE_BYTES)
{
    unsigned char *data = (unsigned char*) malloc(SIZE_BYTES);

    std::ifstream image(FILENAME);
    image.read((char*) data, SIZE_BYTES);
    image.close();

    return data;
}

4
不要混用C和C++,这样就可以正常工作。 - Griwes
5
首先,如果您正在使用C++,请不要使用malloc()函数,我们有new来代替它。话虽如此,请检查image.read的返回值 - 它是否返回了SIZE_BYTES或更少?如果您正在读取原始数据,则可能需要以二进制模式打开文件。 - Alex1985
5
@Alex1985,不,我们有比new更好的基元。我们有容器,智能指针——new几乎从来不是一个答案。 - Griwes
虽然在C++中使用malloc()不是正确的方式,但它仍然可以工作。你们为什么说问题出在malloc上? :-/ - Javid
2
@Javid 更可能的问题是您没有以二进制模式打开文件。如果您在Windows(和大多数其他非Unix系统)下以文本模式读取二进制文件,则会导致数据丢失:所有0x0D将被删除,并且第一个0x1A将终止输入。 - James Kanze
显示剩余6条评论
2个回答

6

1) 以二进制模式打开文件。

2) 不要返回需要释放的原始指针。

std::string readImageFromFile(const char* filename)
{
    std::ifstream image(filename, std::ios::binary);
    std::ostringstream data;
    data << image.rdbuf();
    return data.str();
}

或者,如果你喜欢编写容易出错的代码(似乎在嵌入式领域很受欢迎),你可以这样做:

char* readImageFromFile(const char* filename)
{
    std::ifstream image(filename, std::ios::binary);
    std::ostrstream data;
    data << image.rdbuf();
    data.freeze();
    return data.str();
}

当然,strstreams被弃用是有充分的理由的。


我需要返回一个原始指针。我不想要一个std::string。我可能应该提到这段代码正在微处理器上运行。 - Jean-Luc
1
好的,为了避免使用 std::string,我更新了答案,如果你更喜欢这种方式。 - Jonathan Wakely
它肯定受到嵌入式人群的欢迎!说实话,我确实需要它这样,因为我正在使用opencv,需要用从该文件返回的指针击打cv::Mat的数据指针。 - Jean-Luc
1
你可以很好地使用std::string与opencv或类似的库。仅使用指针,你会出错的。例如,在这里,你如何告诉返回值有多大?它是二进制的,在结尾没有\0字符。使用std::string或std::vector。然后使用std::string().c_str()或&std::vector[0]来传递指针给仅支持C的函数。它将在函数结束时自动释放。 - Pihhan

3
尝试使用std::ifstream image(FILENAME, std::ios_base::binary);(注意ifstream构造函数的第二个参数)。

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