I realize that ofstream doesn't work on Windows 7 hidden file.
Here is the quick test code.
#include <fstream>
#include <iostream>
#include <tchar.h>
#include <windows.h>
int main() {
{
std::ifstream file2(_T("c:\\a.txt"));
if (file2.is_open()) {
std::cout << "ifstream open" << std::endl;
} else {
std::cout << "ifstream not open!" << std::endl;
}
}
// SetFileAttributes(_T("c:\\a.txt"), FILE_ATTRIBUTE_NORMAL);
SetFileAttributes(_T("c:\\a.txt"), FILE_ATTRIBUTE_HIDDEN);
{
std::ofstream file(_T("c:\\a.txt"));
if (file.is_open()) {
std::cout << "ofstream open" << std::endl;
} else {
std::cout << "ofstream not open!" << std::endl;
}
}
getchar();
}
Here is the output I am getting
ifstream open
ofstream not open!
If I am using FILE_ATTRIBUTE_NORMAL, ofstream will be opened successfully.
I do not run the program as Administrator. But, I do use the following linker option.
Having to turn No for Enable User Account Control (UAC) is important, if we do not start the application as Administrator. OS will help us to write the actual file to C:\Users\yccheok\AppData\Local\VirtualStore\a.txt instead of protected C:\
Does ofstream fail on Windows 7 hidden file, is an expected behaviour?
Yes. As noted in the underlying CreateFile documentation, " If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, CreateFile fails and sets the last error to ERROR_ACCESS_DENIED if the file exists and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM attribute."
Or more readable: CreateFile fails if both CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, and if the file has the FILE_ATTRIBUTE_HIDDEN and/or FILE_ATTRIBUTE_SYSTEM attribute.
It just so happens that ofstream calls CreateFile like this.
Related
Is there a way to open a file in C++ and see only the context of the file from the state the file was in when it was opened (so if the file was modified while it was opened, the changes won't be visible)?
For example:
#include <iostream>
#include <fstream>
#define CHUNK 100000
int main()
{
std::ifstream m_istr("a.txt", std::ios::binary);
if(!m_istr.is_open())
{
std::cout << "NOT OPENED!" << std::endl;
return -1;
}
auto buffer = new uint8_t[CHUNK];
system("#echo lol >> a.txt");
m_istr.read((char*)buffer, CHUNK);
std::cout << buffer << std::endl;
}
I do not want to see the string lol appended to my buffer.
I can make an exclusive tmp copy file, open it and after I am done delete it, but I am wandering if there is a cleaner solution.
Yes, there is a cleaner solution. But it is OS specific.
For example, in Windows you can open file with exclusive access rights. Something like this:
For example: HANDLE hFile = ::CreateFile(lpszFileFullPathName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
I am using std::fstream to read and write to the same file. I can see the write happening but not the read.
After searching the web, I got to know that I can not set in and app mode together. So, got rid of that and made it very simple of not passing any arguments.
I am very interested to know the reason why read is not happening.
Also, how do people read and write to the same file using same fstream?
My code:
#include<iostream>
#include<fstream>
int main() {
std::fstream* fs = new std::fstream("xx.txt");
*fs << "Hello" << std::endl;
(*fs).close(); // ?
std::string line;
while(std::getline(*fs, line)) {
std::cout << line << std::endl;
}
}
With this code, I can xx.txt contain "Hello" as its content but it does not go inside the while loop at all stating that reading failed.
How can I overcome this?
You forgot to reopen the stream. Actually you can't open a stream in both directions (at the same time).
So the steps are:
Open the stream for writing
Write data
Close the stream
Reopen the stream for reading
Read data
Close it (optional)
Your sample can be rewritten as:
#include <fstream>
#include <iostream>
int main()
{
const std::string file_path("xx.txt");
std::fstream fs(file_path, std::fstream::app);
if(fs) // Check if the opening has not failed
{
fs << "Hello" << std::endl;
fs.close();
}
fs.open(file_path, std::fstream::in);
if(fs) // Check if the opening has not failed
{
std::string line;
while(std::getline(fs, line))
{
std::cout << line << std::endl;
}
fs.close();
}
return 0;
}
Note that it is a good idea to check if the stream is successfully open before trying to use it.
I will try to explain the issue.
Statement std::fstream* fs = new std::fstream("xx.txt"); will open file if it exists in default mode "in|out" .
If the file does not exist then the call to open from inside of constructor std::fstream will fail. And this can be checked by checking failbit using function fail(). So you will explicitly need to call 'open' to use the fstream object for data input. Note: the new file will not be created unless you call 'close'.
You can test this by actually trying to open an existing file or new file you can see the difference.
So alternatively what you should do is always call 'open' which will work in both cases (if file exists or not).
#include<iostream>
#include<fstream>
int main() {
//std::fstream fs("xx.txt");
//std::cout << fs.fail() << std::endl; // print if file open failed or passed
std::fstream fs;
fs.open("xx.txt", std::fstream::in | std::fstream::out | std::fstream::app);
std::cout << fs.fail() << std::endl;
fs << "Hello" << std::endl;
if (fs.is_open())
{
std::cout << "Operation successfully performed\n";
fs.close();
}
else
{
std::cout << "Error opening file";
}
For reading the content of the file you will first need to close the file. And then reopen and read. As I understand once you start using the object fs for insertion you cannot read from it unless you explicitly close it and reopen.
fs.open("xx.txt", std::fstream::in | std::fstream::out);
std::string line;
while(std::getline(fs, line)) {
std::cout << line << std::endl;
}
std::cout << "end" << std::endl;
fs.close();
}
Newb here. I have spent the last 4 hours trying to solve this problem.
ifstream is suddenly not opening files.
ofstream has no problems writing to the file.
The file exists, it's contents are, ThisIsText, and it is in the reference directory, which I confirmed with system("dir & pause")
I tried Code::Blocks and Dev C++, but I think they're using the same compiler(GNU GCC Compiler).
I tried using the full filename path with double backslashes.
I see people mentioning permissions, but I don't know how to tinker with that.
I'm on Windows 10.
Edit: I just found a new compiler(Embarcadero 10.1 AKA Borland) and the code works with it. I still want to know what the problem is with GNU GCC
The following code skips to the else statement:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string message;
ifstream inputFile;
inputFile.open("File.txt");
if (inputFile.good())
{
inputFile >> message;
cout << message;
system("dir & pause");
}
else
{
cout << "failed to open input file\n";
system("dir & pause");
} return 0;
}
If it helps, I found the following code online and it outputs, "Error code = 2"
from winerror.h, that is: ERROR_FILE_NOT_FOUND
#include <windows.h>
#include <iostream>
int main()
{
HANDLE hFile = CreateFile(
"one.txt", // Windows does not case about case
GENERIC_READ,
0, // no sharing
NULL, // default security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ); // no file template
if(INVALID_HANDLE_VALUE == hFile)
{
DWORD errCode = GetLastError(); // see winerror.h for meanings
std::cout << "File wouldn't open :-(" << std::endl;
std::cout << "Error code = " << errCode << std::endl;
}
else
{
std::cout << "File opened OK :-)" << std::endl;
CloseHandle(hFile);
}
return 0;
}
PS. I know using namespace std; is bad practice
Is there any way in C++ to detect if a file is already open in another program?.I want to delete and rewrite some files, but in case a file is opened I want to display an error message. I am using Windows OS.
Taking an action depending on the result of the "is file open query" is a race condition (the query returns false and then a program opens the file before your program attempts to delete it for example).
Attempt to delete the file using DeleteFile() and if it fails display the reason the file delete failed, using GetLastError(). See System Error Codes for the list of error codes (ERROR_SHARING_VIOLATION which states "The process cannot access the file because it is being used by another process.")
You can use CreateFile API function with the share mode of NULL, which opens the file for exclusive use.
You can use remove("filename") function.
you can use is_open() to check if the file is open. If it is you can close it or do somehting else.
Here is an exampe:
int main ()
{
fstream filestr;
filestr.open ("test.txt");
if (filestr.is_open())
{
filestr << "File successfully open";
filestr.close();
}
else
{
cout << "Error opening file";
}
return 0;
}
#include <iostream> // std::cout
#include <fstream> // std::ofstream
int main () {
std::ofstream ofs;
ofs.open ("example.txt");
if (ofs.is_open())
{
ofs << "anything";
std::cout << "operation successfully performed\n";
ofs.close();
}
else
{
std::cout << "Error opening file";
}
return 0;
}
I'm trying to use the ofstream class to write some stuff to a file, but all that happens is that the file gets created, and then nothing. I have some simply code here:
#include <iostream>
#include <fstream>
#include <cstring>
#include <cerrno>
#include <time.h>
using namespace std;
int main(int argc, char* argv[])
{
ofstream file;
file.open("test.txt");
if (!file) {
cout << strerror(errno) << endl;
} else {
cout << "All is well!" << endl;
}
for (int i = 0; i < 10; i++) {
file << i << "\t" << time(NULL) << endl;
}
file.flush();
file.close();
return 0;
}
When I create a console application, everything works fine, so I'm afraid this code is not completely representative. However, I am using code like this in a much larger project that - to be honest - I don't fully understand (Neurostim). I'm supposed to write some class that is compiled to a dll which can be loaded by Neurostim.
When the code is run, "test.txt" is created and then "No error!" is printed, as this is apparently the output from strerror. Obviously this is wrong however. The application runs perfectly otherwise, and is not phased by the fact that I'm trying to write to a corrupted stream. It just doesn't do it. It seems to me like there is no problem with permissions, because the file is in fact created.
Does anyone have any ideas what kind of things might cause this odd behavior? (I'm on WinXP Pro SP3 and use Visual C++ 2008 Express Edition)
Thanks!
Just a thought :- in your real code are you re-using your stream object?
If so, you need to ensure that you call clear() on the stream before re-using the object otherwise, if there was a previous error state, it won't work. As I recall, not calling clear() on such a stream would result in an empty file that couldn't be written to, as you describe in your question.
ofstream file;
file.open("test.txt");
Just a nit: you can combine that into a single line. ofstream file("test.txt");
if (file) {
cout << strerror(errno) << endl;
} else {
cout << "All is well!" << endl;
}
Your test is backwards. If file is true, it's open and ready for writing.
Also, I wouldn't count on strerror() working correctly on Windows. Most Windows APIs don't use errno to signal errors. If your failure is happening outside the C/C++ run-time library, this may not tell you anything interesting.
UPDATE Thinking more about this, failing to open a file via fstreams is not guaranteed to set errno. It's possible that errno ends up set on some platforms (espeically if those platforms implement fstream operations with FILE* or file descriptors, or some other library that sets errno) but that is not guaranteed. The official way to check for failure is via exceptions, std::io_state or helper methods on std::fstream (like fail or bad). Unfortunately you can't get as much information out of std::streams as you can from errno.
You've got the if statement wrong. operator void* returns NULL (a.k.a. false) if the file is not writable. It returns non-zero (a.k.a. true) if the file is writeable. So you want:
if (!file) {
cout << strerror(errno) << endl;
} else {
cout << "All is well!" << endl;
}
Or:
if (!file.good()) {
cout << strerror(errno) << endl;
} else {
cout << "All is well!" << endl;
}