Reputation: 109
I have a particle system program that generates a .dat
file with particle coordinates in every iteration. The end goal is to run the program multiple times via a script with different parameters. So, I am trying to setup my program in a way that, for every run, all relevant data are going to be stored in a folder.
What I do is to generate PNGs
from the .dat
files with Gnuplot
, call ffmpeg
to create a video out of the PNGs
, use WinRAR
to compress the .dat
files and finally clean up, by deleting all the intermediate files. This works, when I do it in the working directory.
Now I try to create a new directory and do the same stuff in there. My code:
// Load the proper library to use chdir() function
#ifdef _WIN32
#include <direct.h>
#elif defined __linux__ || defined __APPLE__&&__MACH__
#include <unistd.h>
#endif
// Make output directory and change working directory to new directory
ostringstream dirCommand;
dirCommand << "mkdir " << folderName_str;
system(dirCommand.str().c_str());
const char* test = folderName_str.c_str();
#ifdef _WIN32
if(_chdir(test))
{
printf( "Unable to locate the directory: %s\n",test);
return;
}
#elif defined __linux__ || defined __APPLE__&&__MACH__
if(chdir(test))
{
printf( "Unable to locate the directory: %s\n",test);
return;
}
#endif
else
printf("Created output directory...\n");
Already for this part, I know that there are going to be objections. I have looked extensively on SO and many people favor SetCurrentDirectory()
for Windows, or they are skeptical about using system()
. In my defense, I am a novice programmer and my knowledge is really limited...
Now, when I try to make the video with FFMpeg
and then rar/tar my files:
// Make video
std::cout << "Generating Video..." << endl;
ostringstream command;
command << "ffmpeg -f image2 -r 1/0.1 -i output_%01d.png -vcodec mpeg4 " << videoName_str << ".avi -loglevel quiet";
std::system(command.str().c_str());
// Clean Up!
std::cout << "Cleaning up!" << endl;
ostringstream command2;
#ifdef _WIN32
command2 << "rar -inul a " << videoName_str << ".rar *.dat settings.gp loadfile.gp";
#elif defined __linux__ || defined __APPLE__&&__MACH__
command2 << "tar cf " << videoName_str << ".tar *.dat settings.gp loadfile.gp";
#endif
std::system(command2.str().c_str());
I get very different behaviors in Win/ Linux.
In windows, the folder is created. The .dat
files are generated correctly and gnuplot
plots the PNGs
as well. When ffmpeg
is called, nothing happens. No error message from FFMpeg
or anything. The same goes for WinRAR
. Maybe, for the last thing, I can use the command line utility of 7z
which is free!
Strangely enough, the behavior is inverted from that of Windows. As soon as the dir is changed, only the first .dat
file is generated. It is as if every subsequent call I make to fprintf()
for my file generation does not work, or gets lost somewhere. Gnuplot
works, as do ffmpeg
and tar
!!
I am really perplexed. Any help, would be really appreciated.
Upvotes: 0
Views: 255
Reputation: 4517
A few points that might be helpful:
Make sure to check the result of every system call, including system() and fprintf().
It's been a while since I last touched Windows; I remember that depending on how binaries were linked, they would not always print out to the same console. So ffmpeg/winrar could be throwing the error messages away, or just allocating a new, short-lived console to print.
I would use mkdir/_mkdir instead of calling system().
With popen()/_popen() you can get more control over the error output.
Consider using a shell script or bat file.
Upvotes: 1