I'm using visual studio 2017, running with the c++17 ISO Standard(not boost) set to be able to use <filesystem>. I'm running into a wall though because everytime I run, whether in debug or release, file_copy() gives me the error access denied. I've checked the other bits of my code and the only thing that isn't working is file_copy(). Does anyone know why I'm getting this error and how to fix it? I'm the administrative account on my PC.
std::vector<std::string> findAndCopyFiles()
{
std::vector<std::string> fileNames;
std::error_code errCode;
errCode.clear();
fs::current_path("C:\\Users\\kenny\\Desktop\\Engine", errCode);
std::cout << errCode.message() << std::endl; errCode.clear();
fs::path pa = fs::current_path();
pa += "\\TEMP";
std::cout << pa.string() << std::endl;
if (fs::create_directory(pa, errCode))//Create directory for copying all files)
{
std::cout << "Directory created successfully" << std::endl;
std::cout << errCode.message() << std::endl; errCode.clear();
}
fs::path tempDir(pa);
fs::path currentDirectory = fs::current_path();
fs::recursive_directory_iterator dirIter(currentDirectory);
for (auto &p : dirIter)
{
if (p.path().extension() == ".cpp" || p.path().extension() == ".h")
{
//std::string fileContents = getFileContents(p.path().string());
std::string fileName = p.path().stem().string();
if (!fs::copy_file(p.path(), tempDir, fs::copy_options::overwrite_existing, errCode))
{
std::cout << "failed to copy file: " << fileName << " from " << p.path().string() << " to " << tempDir.string() <<std::endl;
}
std::cout << errCode.message() << std::endl; errCode.clear();
//ensures file is a cpp file before adding it to list of fileNames
if (p.path().extension().string() == ".cpp")
{
auto it = std::find(fileNames.begin(), fileNames.end(), fileName); //seaches TEMP folder for file
if (it == fileNames.end())
{//if file was not found in vector of registered file names, add it
fileNames.push_back(fileName);
}
}
}
}
std::cout << "All files found. " << fileNames.size() << " files were found" << std::endl;
return fileNames;
}
As per the comments. You were trying to overwrite a directory with a regular file. From the documentation [trimmed]
o Otherwise, if the destination file already exists...
o Report an error if any of the following is true:
o to and from are the same as determined by equivalent(from, to);
o to is not a regular file as determined by !is_regular_file(to)
So you need to append the filename to the destination directory path using the `std::filesystem::operator/ overload (untested)...
if (!fs::copy_file(p.path(), tempDir / p.filename(), fs::copy_options::overwrite_existing, errCode))
Related
I am trying to stream the data in the retrieved s3 file into a local file on disk. However, when I try my current code, I do not get a file stored on my computer, or in any location near the code.
I first request the object from s3 using a getObjectOutcome. After success, I want to create an ofstream and redirect the objects stream buffer to my local object so that I can create a file on disc. However, the following code does not create a file on my computer. What am I doing wrong?
Here is the get object function:
bool GetObject(const Aws::String& objectKey,
const Aws::String& fromBucket,
const Aws::Client::ClientConfiguration& clientConfig) {
Aws::S3::S3Client client(clientConfig);
Aws::S3::Model::GetObjectRequest request;
request.SetBucket(fromBucket);
request.SetKey(objectKey);
Aws::S3::Model::GetObjectOutcome outcome =
client.GetObject(request);
if (!outcome.IsSuccess()) {
const Aws::S3::S3Error& err = outcome.GetError();
std::cerr << "Error: GetObject: " <<
err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
}
else {
std::cout << "Successfully retrieved '" << objectKey << "' from '"
<< fromBucket << "'." << std::endl;
std::ofstream localfile;
localfile.open(objectKey.c_str(), std::ios::out | std::ios::binary);
auto retrieved = outcome.GetResult().GetBody().rdbuf();
localfile << retrieved;
std::cout << "Done!";
}
return outcome.IsSuccess();
}
Here is an image of the memory for local file and retrieved:
Would someone teach me what I am doing this wrong, or how to correctly download data from s3 to disc?
Thanks.
I tried downloading some data from s3 to disc. I am having trouble outputting this data via stream buffer to local file. I have been looking online and cannot find a similar problem.
Update:
I am now on my second day of trying to figure this out to no avail. For some reason, the code will not even output a file after it has been created to the directory I have set up for the .nc files to be written to.
I have tried the following updates:
bool GetObject(const Aws::String& objectKey,
const Aws::String& fromBucket,
const Aws::Client::ClientConfiguration& clientConfig) {
Aws::S3::S3Client client(clientConfig);
Aws::S3::Model::GetObjectRequest request;
request.SetBucket(fromBucket);
request.SetKey(objectKey);
Aws::S3::Model::GetObjectOutcome outcome =
client.GetObject(request);
if (!outcome.IsSuccess()) {
const Aws::S3::S3Error& err = outcome.GetError();
std::cerr << "Error: GetObject: " <<
err.GetExceptionName() << ": " << err.GetMessage() << std::endl;
}
else {
std::cout << "Successfully retrieved '" << objectKey << "' from '"
<< fromBucket << "'." << std::endl;
//create the filename, which will be the objectKey
std::string local_file_name = "./netcdf/" + objectKey;
std::ofstream local_file(local_file_name, std::ios::binary);
auto &retrieved = outcome.GetResult().GetBody();
local_file << retrieved.rdbuf();
std::cout << "Done!";
}
return outcome.IsSuccess();
}
Then, after opening the ./netcdf folder, there is no output.
Here is the file structure inside my project for reference with the code:
I am still confused as to what I need to do here.
Thank you for all of the help you can offer!
You are using a folder with "./" at the front. This means that the file will be relative to the current working directory (cwd) of the binary. That is likely not the src folder
Just to get past your problem, use a full absolute path to see if the rest of your code works.
Also, try adding
// You need "#include <filesystem>" for the next line
cout << std::filesystem::current_path();
To see where the files you made might be
I'm trying to delete Windows Defender's scans history and backup history using C++, but I have no clue how I can do it.
I'm using this code:
std::string wdefenderhistory = "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\History"; //defender history
std::string wdefenderbackupstore = "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\BackupStore"; //defender backups
if (std::filesystem::exists(wdefenderhistory)) {
std::filesystem::remove_all(wdefenderhistory);
}
if (std::filesystem::exists(wdefenderbackupstore)) {
std::filesystem::remove_all(wdefenderbackupstore);
}
I tried already with std::fs::remove() and std::remove(), but nothing works.
Any way to force deleting a folder with admin rights without using system() / ShellExecute() syntax?
Started the program as admin, etc etc - nothing works, so I'm asking there.
std::fs::remove_all() is also giving me a memory error:
I'm sure for 99% that error code will be 0x5
I noticed that some folders in directory (only CacheManager and everything under it needs) does not needs the "admin" perms,
so i solved the problem with:
code is deleting every folder w/o admin privilege and keeps C:\..\History path :)
std::string wdefenderhistory = "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\History"; //defender history
std::string wdefenderbackupstore = "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\BackupStore"; //defender backups
if (std::filesystem::exists(wdefenderhistory)) {
const std::filesystem::path defenderhist{ "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\History" };
for (auto const& dir_entry : std::filesystem::recursive_directory_iterator{ defenderhist })
{
try {
const std::filesystem::path cachemanager{ "C:\\ProgramData\\Microsoft\\Windows Defender\\Scans\\History\\CacheManager" };
for (auto const& dir_entryy : std::filesystem::recursive_directory_iterator{ cachemanager })
{
if (dir_entry != dir_entryy && dir_entry != cachemanager) {
std::filesystem::remove_all(dir_entry);
}
}
}
catch (std::filesystem::filesystem_error const& ex) {
std::cout
<< "what(): " << ex.what() << '\n'
<< "path1(): " << ex.path1() << '\n'
<< "path2(): " << ex.path2() << '\n'
<< "code().value(): " << ex.code().value() << '\n'
<< "code().message(): " << ex.code().message() << '\n'
<< "code().category(): " << ex.code().category().name() << '\n';
}
}
}
Please mark this thread as solved because i dont know how to do it, thank you
This question already has answers here:
Create a directory if it doesn't exist
(10 answers)
Closed 3 years ago.
I need to create a text file in my program's subdirectory to write some data. The lines below do not work, the folder is not created. The file is not created even if I create the subfolder manually. Without subfolder in line this command works perfectly.
FILE* f;
if (fopen_s(&f, "/Sandbox/OUTPUT.txt", "w"))
return 1; // Nothing happens
if (fopen_s(&f, "//Sandbox//OUTPUT.txt", "w"))
return 1; // Nothing happens
if (fopen_s(&f, "\\Sandbox\\OUTPUT.txt", "w"))
return 1; // Nothing happens
if (fopen_s(&f, "\Sandbox\OUTPUT.txt", "w"))
return 1; // Nothing happens
if (fopen_s(&f, "Sandbox/OUTPUT.txt", "w"))
return 1; // Nothing happens
if (fopen_s(&f, "Sandbox\OUTPUT.txt", "w"))
return 1; // Creates a file named 'SandboxOUTPUT.txt'
How to code this correctly?
If you have a C++17 enabled compiler, make use of std::filesystem. Here's an introduction to some of the things you can do with it that should be pretty self-explanatory, but if anything is unclear, ask and I'll try to clarify.
#include <filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
int main() {
// create a path in an OS agnostic manner
fs::path dir_path = fs::path(".") / "Sandbox";
fs::directory_entry dir(dir_path);
if(dir.exists()) {
std::cout << dir << " already exists\n";
if(dir.is_directory() == false) {
std::cerr << "... but is not a directory\n";
return 1;
}
} else {
std::cout << "creating dir " << dir << "\n";
if(fs::create_directory(dir) == false) {
std::cerr << "failed creating " << dir << "\n";
return 1;
}
}
{
// create a path to your file:
fs::path filename = dir_path / "OUTPUT.txt";
std::cout << "creating file " << filename << "\n";
std::ofstream os(filename);
if(os)
os << "Hello world.\n";
else {
std::cerr << "failed opening " << filename << " for writing\n";
return 1;
}
}
}
I suppose you're working in a Windows environment.
In case the Sandbox folder is a subdirectory of the current directory, you should use "Sandbox\\OUTPUT.txt" or ".\\Sandbox\\OUTPUT.txt".
If it's a folder within the root of the drive, then use "C:\\Sandbox\\OUTPUT.txt".
In other words, a backslash needs to be escaped by means of another backslash.
If you want to create the directory first, then try:
mkdir(".\\Sandbox") or mkdir("C:\\Sandbox").
I have a JSP to upload a file which works fine. After the file has been uploaded I am trying to open the file again using the file path saved from the form data.
However, the filepath variable shows fine but the ifstream fails. If the csvFileName variable is set manually to path + file name it works fine. Doing this on a MAC and trying to avoid using boost library.
form_iterator two = cgi.getElement("csvFileName");
csvFileName=two->getValue();
form_iterator three = cgi.getElement("csvFilePath");
filePath = three->getValue();
csvFileName.c_str();
ifstream thefile;
thefile.open(csvFileName);
cout << "Filename is: " << csvFileName << endl;
if (thefile.is_open())
{
cout << "<H1>It's working</H1>" << endl;
while ( getline (thefile,line) )
{
cout << line << '\n';
}
thefile.close();
}
else
{
cout << strerror(errno) << endl;
}
I have a C++ program that reads a config file and gets the directories.
What I want to do now is to execute an .exe program using the directory settings from the config file.
Here is a piece of my code:
int main(){
ConfigFile cfg("htbaseconfig.properties");
bool exists = cfg.keyExists("backuplocation");
exists = cfg.keyExists("logdir");
exists = cfg.keyExists("execdir");
exists = cfg.keyExists("fulldir");
exists = cfg.keyExists("incdir");
exists = cfg.keyExists("appdir");
std::string bkploc = cfg.getValueOfKey<std::string>("backuplocation");
std::cout << "Backup Location: " << bkploc << "\n";
std::string bkplogdir = cfg.getValueOfKey<std::string>("logdir");
std::cout << "Log Location: " << bkplogdir << "\n";
std::string bkpexec = cfg.getValueOfKey<std::string>("execdir");
std::cout << "Exec Directory: " << bkpexec << "\n";
std::string bkpfulldir = cfg.getValueOfKey<std::string>("fulldir");
std::cout << "Full Directory: " << bkpfulldir << "\n";
std::string bkpappdir = cfg.getValueOfKey<std::string>("appdir");
std::cout << "Real app Directory: " << bkpappdir << "\n\n\n";
for( ; ; ) {
Sleep(6000);
ShellExecute(NULL, L"open", , L"C:\\teste.htm", NULL,SW_SHOWNORMAL);
}
std::cin.get();
return (0);}
Inside the ShellExecute, I wanted to execute the following line parsing the config options:
$execdir/program.exe $logdir/log.txt $bkpappdir $bkploc
How do I do this? I want to execute my program with the variables I get on std::cout.
You must pass to ShellExecute, instead of the second NULL, a string (c string, a char[]) that contains all parameters, like if you are passing them to the command line.
So Will be something like
ShellExecute(NULL, L"open", , L"C:\\teste.htm", "option=param option2=param2",SW_SHOWNORMAL);
Depends on how you parse them (or how they are parsed) from the other exe file