I have the following code:
ifstream initFile;
initFile.open("D:\\InitTLM.csv");
if(initFile.is_open())
{
// Process file
}
The file is not opening. The file does exist on the D: drive. Is there a way to find out exactly why this file cannot be found? Like an "errno"?
You should be able to use your OS's underlying error reporting mechanism to get the reason (because the standard library is built on the OS primitives). The code won't be portable, but it should get you to the bottom of your issue.
Since you appear to be using Windows, you would use GetLastError to get the raw code and FormatMessage to convert it to a textual description.
Answered here I believe: Get std::fstream failure error messages and/or exceptions
The STL is not great at reporting errors. Here's the best you can do within the standard:
ifstream initFile;
initFile.exceptions(ifstream::eofbit|ifstream::failbit|ifstream::badbit);
try
{
initFile.open("D:\\InitTLM.csv");
// Process File
}
catch(ifstream::failure e)
{
cout << "Exception opening file:" << e.what() << endl;
}
In my experience, the message returned by what() is usually useless.
Check the permissions on the root of the D: drive. You may find that your compiled executable, or the service under which your debugger is running, does not have sufficient access privileges to open that file.
Try changing the permissions on the D:\ root directory temporarily to "Everyone --> Full Control", and see if that fixes the issue.
Related
I have a problem. I'm writing to a log file, but when I do the application throws:
An unhandled exception of type 'System.AccessViolationException' occurred in ****
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
The code (unmanaged) I'm using is this one:
inline bool writeLog(string message)
{
ofstream myfile;
myfile.open(mStrSource.c_str(), ios::in | ios::out | ios::app);
if(!myfile.is_open())
{
throw "Unable to open the file: " + mStrSource;
}
myfile << "TESTE" << endl;
myfile.close();
return true;
};
When receiving this error, the code points to the _Lock() of file fstream:
virtual void __CLR_OR_THIS_CALL _Lock()
{ // lock file instead of stream buffer
if (_Myfile)
_CSTD _lock_file(_Myfile);
}
Other info:
Developed under VS2010 (Incially the project was Winx32 but now it's Winx64) (.NET Framework 4).
The open() method of ofstream creates the file and the file is writable but throws the exception when try's to write on the file.
Thank you guys in advanced.
Check to make sure your application has rights to write to a file in that location. A standard user in Windows cannot access the whole file system (especially for writing). Either require the app to have admin rights (not recommended for "normal" apps) or write to a place that standard users can get to (e.g. My Documents directory).
Also, make sure the file is not opened for exclusive use by another app like Excel or Word. They have a habit of locking files when opening them.
Another thing to look at is during development, sometimes the .NET runtime/VS debugger will leave a file locked that you were working with after a crash. Try closing/reopening Visual Studio to help with that.
Ok guys,
For future notice, the problem was related to the configuration of the project. When I converted the project from vs2008 to vs2010, from .net 3.5 to .net 4 and from x32 to x64 something didn't quite go right.
So I reverted everything back and converted again in a more controlled environment and now i can open/write/close files without a problem.
Thanks anyway guys.
I've written the following source code:
ifstream leggiFile;
leggiFile.open("Questions.txt",ios::in);
if (!leggiFile.good())
{
cerr << "\n\n\n\tErrore during file opening Questions.txt\n\n\n" << endl;
}
else
{
// ...
};
leggiFile.close();
system("pause");
Now I'd like to use the same object for working with a second file.
leggiFile.open("Answers.txt",ios::in);
i=0;
if(!leggiFile.good())
{
cerr << "\n\n\n\tError during opening of file answers.txt\n\n\n" << endl;
}
else
{
// ...
}
Problem: The 2nd time the file cannot be opened and the error message appears. Why?
Could you please suggest me a solution?
It's possible that you've done work on the stream that set one or more of the error flags, such as eofbit.
Closing the stream doesn't clear its error flags, you have to do it manually. Call leggiFile.clear(); after you close it.
Since C++11, this is done automaticaly by open(), though. If you're already using a C++11 compiler, your problem is elsewhere (can't say where, you haven't shown enough code).
Learn singleton design pattern for logging or any multiple access to any file. You can also use Mutex lock so that code will be waited for resources like files. But it is not wise to use same file simultaneously. File can be open for a lyfecycle of code. It is not a issue.
I tried to write some code in C++ that traverses all system files. The problem was that there are some files which returns an error (2) which mean no such file found. Although the path had been found, but cannot been opened or get the pointer on that file or folder!
dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data);
if (dirp->search_handle == INVALID_HANDLE_VALUE)
{
cout << "Error(" << errno << ") opening " << dir<<" erroeno:"<<strerror(errno)<< endl<<endl;
}
The problem is not caused by a lack of administrator permissions because I am an admin on my computer. So what might cause this problem?
There are other reasons you could lack permissions
You could be trying to traverse a directory owned by another user on your domain. Being an Administrator doesn't automatically give you access to all files on a machine.
What you're passing could just have a trivial error. For example, you might have passed "C:\temp", without properly escaping your backslash, and instead getting a tab character.
I would provide more information about what specifically you're passing, or perhaps read up on msdn
I would like to know how to check if I have write permissions to a folder.
I'm writing a C++ project and I should print some data to a result.txt file, but I need to know if I have permissions or not.
Is the check different between Linux and Windows? Because my project should run on Linux and currently I'm working in Visual Studio.
The portable way to check permissions is to try to open the file and check if that succeeded. If not, and errno (from the header <cerrno> is set to the value EACCES [yes, with one S], then you did not have sufficient permissions. This should work on both Unix/Linux and Windows. Example for stdio:
FILE *fp = fopen("results.txt", "w");
if (fp == NULL) {
if (errno == EACCES)
cerr << "Permission denied" << endl;
else
cerr << "Something went wrong: " << strerror(errno) << endl;
}
Iostreams will work a bit differently. AFAIK, they do not guarantee to set errno on both platforms, or report more specific errors than just "failure".
As Jerry Coffin wrote, don't rely on separate access test functions since your program will be prone to race conditions and security holes.
About the only reasonable thing to do is try to create the file, and if it fails, tell the user there was a problem. Any attempt at testing ahead of time, and only trying to create the file if you'll be able to create and write to it is open to problems from race conditions (had permission when you checked, but it was removed by the time you tried to use it, or vice versa) and corner cases (e.g., you have permission to create a file in that directory, but attempting to write there will exceed your disk quota). The only way to know is to try...
The most correct way to actually test for file write permission is to attempt to write to the file. The reason for this is because different platforms expose write permissions in very different ways. Even worse, just because the operating system tells you that you can (or cannot) write to a file, it might actually be lying, for instance, on a unix system, the file modes might allow writing, but the file is on read only media, or conversely, the file might actually be a character device created by the kernel for the processes' own use, so even though its filemodes are set to all zeroes, the kernel allows that process (and only that process) to muck with it all it likes.
Similar to the accepted answer but using the non-deprecated fopen_s function as well as modern C++ and append open mode to avoid destroying the file contents:
bool is_file_writable(const std::filesystem::path &file_path)
{
FILE* file_handle;
errno_t file_open_error;
if ((file_open_error = fopen_s(&file_handle, file_path.string().c_str(), "a")) != 0)
{
return false;
}
fclose(file_handle);
return true;
}
Currently I use something like:
#include <sys/stat.h>
#include "My_Class.h"
void My_Class::my_function(void)
{
std::ofstream my_file;
struct stat file_info;
if ( filename_str.compare("")!=0 &&
stat(filename_str.c_str(),&file_info) == 0 )
{
my_file.open(filename_str.data(),std::ios::trunc);
//do stuff
my_file.close();
}
else if ( filename_str.compare("")==0 )
{
std::cout << "ERROR! ... output filename not assigned!" << std::endl;
}
else
{
std::cout << "ERROR! File :" << std::endl
<< filename_str << std::endl
<< "does not exist!!" << std::endl;
}
}
...is this a decent way to go, or is there a better alternative? Seems like I could run amuck of permissions if I don't have permissions to read the file.
This is NOT a homework, question, it is a question about best practice.
I'd use the boost::filesystem constructs. Not only are they cross platform, they're part of the next standard library.
Generally I think it is best to just try opening it and catch an error.
IMO, checking permissions is unwise because what if it's a Linux box and you check its attributes, decide you can't write to it, but the filesystem supports ACL's and they do grant you permission? (As a sysadmin I can't stand when apps do this. I like ACL's and if you're an app, don't tell me you can't write to a file unless you've tried first.)
Conceptually, I'd say it depends on what you're planning to do with that file..
If you need its contents, go ahead and try to open it, and be prepared to handle failure gracefully, for the reasons Ken detailed.
If you are not currently interested in its contents (for example, when enumerating directory contents, or only planning to access a file at some point in the future, etc.), you might be better off just checking attributes for now. Otherwise, nasty things like hierarchical storage management may trigger an expensive (=slow) recall of file contents from, say, a tape backup or network (whereas attributes may have been cached). You could try to avoid that by checking for respective file attributes, but that's additional complexity, too.
So as a best practice, I'd suggest to open files sparingly (i.e., if you're not immediately interested in the contents, contend yourself with file attribute-based information), AND handle failure strictly in response to the actual call that opens the file when you need it.