在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 的答案作为公认的答案。
答案 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”而不是二进制数据。
如果是这样,您需要手动重新转换此文本数据。