यह ठीक काम करने वाले कोड का परिणाम है। मेरे पास इसे अभी पोस्ट करने के लिए कुछ समय है अगर यह किसी की मदद कर सकता है। मेरे लिए यह समझना थोड़ा कठिन था कि बाइटा कैसे काम करता है लेकिन आखिरकार इसका समाधान हो गया। समुदाय को सादर प्रणाम।
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include "libpq/libpq-fs.h"
#include "libpq-fe.h"
#pragma comment(lib, "libpq.lib") /*!< Only for windows compilation */
int main(int argc, char* argv[])
{
ManageDB manager;
manager.conn = manager.ConnectDB(); // My manager, connects ok
const char* fileName = {"test.png"};
const char* fileNameOut = { "testOut.png" };
FILE* file = fopen(fileName, "rb");
if (file == NULL) cout << endl << "FILE WAS UNABLE TO BE READED" << endl;
fseek(file, 0, SEEK_END);
long int fileSize = ftell(file);
rewind(file);
unsigned char* buffRead = (unsigned char*)malloc(fileSize);
size_t bytes_read = fread(buffRead, 1, fileSize, file);
if (bytes_read != fileSize) cout << endl << "fread reading Error";
fclose(file);
size_t* sizeP = new size_t(fileSize);
const char* paramValues[3];
paramValues[0] = "1";
paramValues[1] = fileName;
paramValues[2] = reinterpret_cast<const char*>(buffRead); // type cast required to PQexeParams
const int paramFormats[3]{ 0,0,1 }; //0 = text, 1 = binary
const int paramLenghts[3]{ strlen(paramValues[0]), strlen(paramValues[1]), fileSize};
PGresult *res = PQexecParams(manager.conn, "INSERT INTO filebyte (id, filename, file) VALUES($1::text, $2::text, $3::bytea)",
3, /* params num */
NULL, /* let the backend deduce param type */
paramValues,
paramLenghts,
paramFormats,
1);
if (res && PQresultStatus(res) == PGRES_COMMAND_OK) cout << endl << "Inserted data to filebyte OK";
PQfreemem(res);
//************************download from DB*************************
const char* bytesFromDB = new const char[fileSize];
int sizeR;
// Table columns = id(text) | filename(text) | file(bytea)
const char* sentenceEx = "SELECT file FROM filebyte WHERE id='1'";
res = PQexec(manager.conn, sentenceEx);
if (res && PQresultStatus(res) == PGRES_TUPLES_OK)
{
sizeR = PQgetlength(res, 0, 0);
bytesFromDB = PQgetvalue(res, 0, 0);
}
else cout << endl << "Error at inserting file data in filebyte table";
string hex(bytesFromDB, 2, sizeR-2); //removing the first '\x' characters of the result.
// vars for converting to real bytes process
std::basic_string<uint8_t> bytes;
bytes.clear();
std::string nextbyte;
nextbyte.clear();
uint16_t byte;
// Iterate over every pair of hex values in the input string (e.g. "18", "0f", ...)
for (size_t i = 0; i < hex.length(); i += 2)
{
// Get current pair and store in nextbyte
nextbyte = hex.substr(i, 2);
// Put the pair into an istringstream and stream it through std::hex for
// conversion into an integer value.
// This will calculate the byte value of your string-represented hex value.
std::istringstream(nextbyte) >> std::hex >> byte;
// As the stream above does not work with uint8 directly, we have to cast it now.
// As every pair can have a maximum value of "ff",
// which is "11111111" (8 bits), we will not lose any information during this cast.
bytes.push_back(static_cast<uint8_t>(byte));
}
// string obj from bytes-"array"
std::string result(begin(bytes), end(bytes));
ofstream myFile(fileNameOut, ios::out | ios::ios_base::binary);
if (myFile.is_open())
{
myFile << result;
myFile.close();
}
else cout << endl << "Impossible to writte the file " << fileNameOut;
manager.CloseConn(manager.conn); //closes connection with database internally ok
PQfreemem(res);
free(buffRead);
delete sizeP;
free((char*)fileName[8]);
free((char*)fileNameOut[11]);
return true;
}