当我试图写'const char *'时,c ++给我标准的字符串/损坏的数据而不是二进制数据

时间:2013-04-02 09:02:55

标签: c++ postgresql c++11 libpq

在C ++(Visual C ++ MFC)中,我有char *来自数据库。这实际上是一张照片。 PostgreSQL将它作为char *返回,因为C ++中没有byte [](至于我知道-yet - :))

问题是,我尝试写这样的图像:

ofstream myFile ("C:\\picture.jpg", ios::out | ios::binary);
myFile.write(contents, size);
myFile.close();

输出如:

\xffd8ffe000104a46494600010101006000600000ffe1005a4578696600.......

我尝试将内容更改为reinterpret_cast<char *>(&contents)然后我得到了一些二进制数据,但只有少数。其余的不在文件中。

我也试过这个:

fstream binary_file("C:\\picture.jpg", ios::out | ios::binary | ios::app);
binary_file.write(reinterpret_cast<char *>(&contents),size);
binary_file.close();

对于reinterpret_cast<char *>(&contents)或没有size的人。文件中仍有少量字节数据。没有了。

我还尝试更改PQgetlength。大小来自postgresql的size方法,所以肯定是这样。 (不能错了吗?)

我最后自己给5000并对C ++说它是\xfdd...。它以5.000输出二进制数据,但事实是,它不符合原始文件。它以“h”开头,然后是不同的......

我还尝试将此数据加载到Chilkat的ByteArray,然后使用其文件访问方法进行编写。 {{1}}仍然得到相同的结果。

那么,主要目标是什么?我在这里失踪了什么?任何帮助将不胜感激。

修改 char * 。很抱歉误会。

结论:由于我的需要,我选择 Craig Ringer *的解决方案。但由于这个问题的性质,我选择 H2CO3 的答案作为公认的答案。

4 个答案:

答案 0 :(得分:3)

如果contents真的是char *而不是数组,那么问题是你传递了指针本身的地址。然后你试图将指针值写入文件。将contents(而不是&contents)传递给fstream::write()

答案 1 :(得分:3)

据我所知,你的输出搞砸了

\xffd8ffe000104a46494600010101006000600000ffe1005a4578696600...

这不是有效的十六进制表示法。你需要这样的东西

\xff\xd8\xff\xe0\x00...

答案 2 :(得分:3)

使用libpqtypes。它负责bytea转换以及未libpq正确内置的各种其他更高级别的数据类型处理。

可以在libpq中使用二进制传输模式,但老实说,使用libpqtypes会更简单,让它处理所有这些。您确实不想处理日期和其他自定义格式值的二进制传输,因此如果您使用二进制传输,通常只应为bytea列指定二进制模式。

答案 3 :(得分:2)

首先,您的输出看起来像一个好的,有效的JPG文件的开头,转换为带有一些自制程序的文本。一些数据库开发人员不喜欢在BLOB中存储二进制数据,并且用于在文本字段bytea中存储二进制文件的本机PostreSQL格式相当不方便。许多开发人员使用Base64,UUENCODE或自制解决方案。

你的第一个片段看起来还不错。你没有给我们内容和大小的定义,但如果它们看起来像它们,它应该工作。它应该输出内容而不做任何改动。因此,要确保问题出在内容中,请启动调试器,在myFile.Write中设置断点并查看内容变量。最有可能它将包含相同的“\ xffd8ffe000”而不是二进制数据。

如果是这样,您需要手动重新转换此文本数据。