File retrieving in MongoDB using C++ Drivers - c++

I am doing one project to make a database application in which i need to store some files in the database and later i need to retrieve those files back to the local system. I am using C++ drivers of the mongoDB..Storing the files on the server is working perfectly and when i am trying to retrieve it back only text files are received as it is but when i am doing it with images, .pdf files or other files format the file is corrupt.Can anyone tell me how i can save the files on local system without any corruption. Thanks
Code:
std::fstream out;
const char* gridfilename="Penguins.jpg";
const char* filename="Temp.jpg";
out.open(filename, ios::out);
DBClientConnection c;
c.connect("localhost");
cout << "connected ok" <<endl;
GridFS gfs = GridFS(c, "Test", "DB");
GridFile gf = gfs.findFile(gridfilename);
if (true != gf.exists()) {
cerr << "There is no file like " << gridfilename << endl;
}
gf.write(out);
out.close();

Related

Always empty metadata

I'm writing audio player using QtMutimedia, and need got audio file metadata.
I'm using this code, but always returns empty strings on every file. How fix this?
Qt 5.15.2 MinGw
QStringList meta = player->availableMetaData();
qDebug() << "File meta: ";
foreach(QString data, meta){
qDebug() << data;
}

Duplicate events received from POCO DirectoryWatcher

I'm trying to use the DirectoryWatcher class from POCO's file system library to monitor a specific folder for changes. The code is pretty simple and looks like this:
Monitor::Monitor() {
pattern = new Glob("/path/to/dir/*.dat",
Glob::GLOB_DOT_SPECIAL);
watcher = new DirectoryWatcher(std::string("/path/to/dir"));
watcher->itemAdded += delegate(this, &Monitor::onFileAdded);
watcher->itemModified += delegate(this, &Monitor::onFileChanged);
}
void Monitor::onFileAdded(const DirectoryWatcher::DirectoryEvent& addEvent) {
if (pattern->match(addEvent.item.path())) {
std::cout << "File added: " << addEvent.item.path() << std::endl;
}
}
void Monitor::onFileChanged(const DirectoryWatcher::DirectoryEvent& changeEvent) {
if (pattern->match(changeEvent.item.path())) {
std::cout << "File changed: " << changeEvent.item.path() << std::endl;
}
}
I'm observing some odd behavior. If I copy a new version of a file over a file that's already in the watched folder, I receive the 'item changed' notification twice. If I open a file that's already in the watched folder, edit its contents and save it, I receive an 'item added' notification followed by an 'item changed' notification.
This is on Ubuntu Linux 14.04 and ext4 file system with POCO 1.4.6p2.
Has anyone else observed similar behavior? Could this be related to some specific characteristic of my machine and the OS/file system combo? Is it possible to filter the unwanted events somehow?
Thanks in advance.

Trouble opening DB environment in Oracle Berkeley DB

I'm new to databases and I wrote this practice program to test Berkeley BDB. I'm getting trouble opening the environment - the error appears in my console and says:
testEnv\_db.001: No such file or directory
Error opening database environment
DbEnv::open: No such file or directory
The code of the console program is based strongly off the examples in the Berkeley DB Transactions guide, and here's the text of the program up to the error, under int main().
String^ key_allkeys = "_ALLKEYS";
String^ key_valcount = "_COUNT";
// 1. Print some information to the screen, prompt user to enter path for key-value pair location:
Console::WriteLine("Oracle Berkeley DB Example Database Creator");
Console::WriteLine();
Console::WriteLine("Enter the path to the text file of key-value pairs:");
String^ kv_path = Console::ReadLine();
// 2. Declare initial variables:
String^ totalkeys;
int totalval;
// 3. Open the database:
u_int32_t env_flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN;
std::string envHome("testEnv");
u_int32_t db_flags = DB_CREATE | DB_AUTO_COMMIT;
Db *dbp = NULL;
const char *file_name = "mydb.db";
DbEnv myEnv(0);
try
{
myEnv.open(envHome.c_str(), env_flags, 0);
dbp = new Db(&myEnv, 0);
dbp->open(NULL, file_name, NULL, DB_BTREE, db_flags, 0);
}
catch(DbException &e)
{
std::cerr << "Error opening database environment: " << std::endl;
std::cerr << e.what() << std::endl;
exc_block(); // Block
return (EXIT_FAILURE);
}
It should be fairly obvious that the program is failing right around the try/catch blocks. I've read the manual (literally RTFM) and I couldn't figure it out - the DB_CREATE flag is specified for both the environment and database, so there shouldn't be an issue here.
Any ideas?
It may simply be that the testEnv directory doesn't exist in the directory where you are running the program? You have to create the environment home directory yourself.
Also, you may wish to specify DB_RECOVER when opening the environment.

Can't extract exe or dll files with quazip (Qt)

I am building a qt framework to download and install application updates (like sparkle for obj-c). The download works, the downloaded zip file is valid and i can extract the contents manually but when I let my framework unzip the contents via quazip the files (dll and exe) contains this and only this string: "MZ" and a special char which is wrong encoded (some kind of square on windows and "ê" on mac), so exactly 3 bytes. When I include a text file (or xml) in the zip file, it will be unzipped correctly, manually and with quazip, so I assume that the library was compiled correctly. Where is my error?
I think this can be part of the solution http://en.wikipedia.org/wiki/DOS_MZ_executable?
Here is my method to install the update:
QuaZip archiveWrapper(filename); // The downloaded zip file
if (archiveWrapper.open(QuaZip::mdUnzip)) {
QuaZipFile archive(&archiveWrapper);
qDebug() << "Extracting files" << archiveWrapper.getFileNameList();
for (bool more = archiveWrapper.goToFirstFile(); more; more = archiveWrapper.goToNextFile()) {
QString filePath = archiveWrapper.getCurrentFileName();
QString destinationPath = QDir::cleanPath(QDir::currentPath() + QDir::separator() + filePath);
QString destinationBackup = destinationPath + "_backup";
qDebug() << "Extract" << filePath << "to" << destinationPath;
QuaZipFile zip(archive.getZipName(), filePath);
zip.open(QIODevice::ReadOnly);
QByteArray data = zip.readAll();
zip.close();
QFile oldFile(destinationPath);
if (oldFile.exists()) {
qDebug() << "Rename" << destinationPath << "to" << destinationBackup;
if (!oldFile.rename(destinationBackup)) {
qWarning("Could not rename %s to %s!", destinationPath.toUtf8().constData(), destinationBackup.toUtf8().constData());
}
}
QFile destination(destinationPath);
destination.open(QIODevice::WriteOnly);
destination.write(data.data());
destination.close();
if (oldFile.exists()) {
qDebug() << "Deleting backup of" << destinationPath;
if (!oldFile.remove()) {
qWarning("Could not delete %s!", destinationPath.toUtf8().constData());
}
}
}
if (archive.getZipError() == UNZ_OK) {
qDebug() << "All files extracted successfully";
qDebug() << "Restarting application...";
archiveWrapper.close();
qApp->quit();
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
} else {
qWarning("Error while extracting files (Error %d)", archive.getZipError());
archiveWrapper.close();
}
} else {
qWarning("Could not open archive to extract contents");
}
Edit:
I found out that data (QByteArray) has the expected size, so I think the problem is that QFile does not write the contents of QByteArray into the exe/dll files the way it should be?
Edit 2:
I've found one error, the file size to write:
destination.write(data.data(), data.size());
instead of
destination.write(data.data());
but still, the exe does not have an icon or is executable (but with the correct file size). For a short time a dos window opens and closes. There is a antivirus software running but there is no alert (and because this is a corporate notebook i am not able to shut it down and the update framework should also be running whether there is a antivirus software running or not).
Edit 3:
Although I thought writing exe files is complicated, it was a mixture of stupid bugs I "implemented" for testing purposes. So the simple
QFile destination(destinationPath);
destination.open(QIODevice::WriteOnly);
destination.write(data.data(), data.size())
is sufficient.

ofstream wont create files in documents folder

I'm trying to make a function for a game I'm making that saves data from the game to a text file in a folder, both with a name provided by the user. I was able to do this in my project folder, and wanted it to be in a more universal place, so I am trying the documents folder.
When I switched the locations, however, the code stopped producing the desired result, and started creating the file and the folder in my program's main directory. (the file is not in the folder, fyi)
void Player::save()
{
system("mkdir \"C:\\Users\\Default\\Documents\\Ice Road\"");
//Make "Ice Road" folder in documents
std::string filename((name + ".txt"));
//make a name (inputed by the user earlier) to later be used to name a text file
std::string command("mkdir ");
//string to be combined with name to make folder
std::string commandString((command + name));
//combine to make string command that creates folder
std::string newDir = ("C:\\Users\\Default\\Documents\\Ice Road\\" + name);
//string to set directory to newly created folder
std::ofstream saveStream;
//open output stream for the saving process
SetCurrentDirectory("C:\\Users\\Default\\Documents\\Ice Road\\");
//set the directory to the Ice Road documents folder (DOES NOT WORK)
system((commandString.c_str()));
//create named folder for the save files.
SetCurrentDirectory(newDir.c_str());
//set the directory to the newly created folder
saveStream.open(filename.c_str());
//Create/open a text file that holds the data being saved
system("echo on");
//turn on echo for debugging
saveStream << name << std::endl
<< difficulty << std::endl
<< health << std::endl
<< warmth << std::endl
<< hunger << std::endl
<< packSpace << std::endl
<< packUsed << std::endl;
saveStream.close();
//input data to save file
system("dir");
//show folder for debugging
system("PAUSE");
//wait for input
}
How could I get this code to create a folder in documents called Ice Road, with the named folder inside and the named text file inside that?
(Documents\Ice Road\yourname\yourname.txt)
I solved the problem. My biggest problem was that I had no access to this folder (UAC), but because I wasn't receiving any errors I didn't think of it. Between that and some other tweaking I got it to work as shown below, running as administrator.
void Player::save()
{
std::string iceroad("C:\\Users\\Default\\Documents\\Ice Road");
//Ice road directory, made into a string variable for easy usage, as recommended by Ben
system("mkdir \"C:\\Users\\Default\\Documents\\Ice Road\"");
//Make Ice Road folder in documents
std::string filename(iceroad + "\\" + name + "\\" + name + ".txt");
//make a name (inputed by the user earlier) to later be used to name a text file, now using full address
std::string command("mkdir ");
//string to be combined with name to make folder
std::string commandString((command + name));
//combine to make string command that creates folder
std::string newDir = (iceroad + "\\" + name);
//string to set directory to newly created folder, simplified
std::cout << filename;
//debugging, as reccommended by Dietmar
std::ofstream saveStream;
//open output stream for the saving process
SetCurrentDirectory(iceroad.c_str());
//set the directory to the Ice Road documents folder
system("dir");
//debugging, as recommended by Dietmar
system((commandString.c_str()));
//create named folder for the save files.
SetCurrentDirectory(newDir.c_str());
//set the directory to the newly created folder
saveStream.open(filename.c_str());
//Create/open a text file that holds the data being saved
system("echo on");
//turn on echo for debugging
saveStream << name << std::endl
<< difficulty << std::endl
<< health << std::endl
<< warmth << std::endl
<< hunger << std::endl
<< packSpace << std::endl
<< packUsed << std::endl;
saveStream.close();
//inputs data to save file
system("dir");
//show folder for debugging
system("PAUSE");
//wait for input
}
Thank you for your constructive critiques, I did take them to heart and implement them.