0

在 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。大小来自 postgresql 的PQgetlength方法,所以这是肯定的。(不会错吧?)

我终于给size了自己,对 C++ 说它是5000. 它输出 5.000 的二进制数据,但事实是,它与原始文件不符。它以“h”开头,然后是不同的东西......

我还尝试将这些数据加载到 Chilkat 的 ByteArray,然后使用它的 oen 文件访问方法写入。仍然得到相同的结果\xfdd...

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

编辑:它是char *。我为我的误会道歉。

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

4

4 回答 4

3

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

于 2013-04-02T09:05:51.813 回答
3

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

\xffd8ffe000104a46494600010101006000600000ffe1005a4578696600...

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

\xff\xd8\xff\xe0\x00...
于 2013-04-02T09:07:32.563 回答
3

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

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

于 2013-04-02T10:14:36.883 回答
2

首先,您的输出看起来像是一个良好、有效的 JPG 文件的开始,该文件通过一些自制程序转换为文本。一些数据库开发人员不喜欢将二进制数据存储在 BLOB 中,而用于将二进制存储在文本字段中的原生 PostreSQL 格式 bytea 相当不方便。如此多的开发者使用 Base64、UUENCODE 或自制解决方案。

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

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

于 2013-04-02T09:22:54.517 回答