Delete-file option before opening a file using QFile::Append - c++

Most of the time I want to iteratively add a line to a file, but before I open the file to append to, I'd want to be sure it is an empty file to start with (delete if exists).
It occurs so often that I am guessing there might be something I overlook.
So, what is the most convenient way to remove a file first before appending?
QFile outfile(filename);
if (outfile.open(QFile::Append | QFile::Text))
// An option like `QFile::DELETE_FIRST` or something would be great.
{
...
}

Just don't use QFile::Append - it will open file in append mode, so that all dta is written to the end of the file. You can see all OpenModeFlag's here. Use QIODevice::Truncate instead.
QIODevice::Truncate If possible, the device is truncated before it is opened. All earlier contents of the device are lost.

Related

How to read contents from file and rewrite contents into it in qt?

I want to read contents from a file, then do some processing, rewrite processed contents into that file.
But after I open file in QIODevice::Truncate mode, then the initial content is empty, but I need initial contents:
QFile update_a_file("some/path/to/file.txt");
update_a_file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate);
QString fileContents(update_a_file.readAll());
qInfo("trial info %s", fileContents.toStdString().c_str());
There is nothing from the output log.
So, how can I read contents, and rewrite(empty initial contents and write new processed contents) into file in one open call? Or are there some other file mode in qt?
You are erasing the contents of the file when you open it with QIODevice::Truncate.
From the docs:
If possible, the device is truncated before it is opened. All earlier contents of the device are lost.
Try taking these steps:
Open the file without Truncate.
Read the content
Close the file
Open the file again, this time with Truncate
Write your modified content.
Close the file.

How to clear a file in append mode in C++

I've a file on which I require multiple operations. Sometimes I just want to append data at the end of the file, sometimes I just want to read from the file, and sometimes, I want to erase all the data and write form the beginning of the file. And then, I again need to append data at the end of file.
I'm using following code:
ofstream writeToTempFile;
ifstream readFromTempFile;
writeToTempFile.open("tempFile.txt", ios::app | ios::out);
readFromTempFile.open("tempFile.txt", ios::in);
// Reading and Appending data to the file
// Now it is time to erase all the previous data and start writing from the beginning
writeToTempFile.open("tempFile.txt", std::ofstream::trunc); // Here I'm removing the contents.
// Write some data to the file
writeToTempFile.open("tempFile.txt", std::ofstream::app); // Using this, I'm again having my file in append mode
But what I've done doesn't work correctly. Please suggest me some solution in C++. ( Not in C)
The problem with the code is:
I wasn't closing the file before I called the method open again on it.
So, close the file before you re-open it with some different permissions.

is there any way to clear the content of a text file dynamically in c++?

I am using ofstream to output some text to a file in ios::app mode within a loop. But after some step, I need to clear the content of the file. I know we can do it by either delete the file and open again or to open it again with ios::trunc, but is there any where I can get it done without close and open the file again?
If you have opened it in ios::app mode, there's no way to clear content without opening it again. ofstream can only put text in a file, and as text files are sequential, you can't directly erase data on them.
Note sure if it is possible with io streams, but in general you can truncate an open file by setting its current position to 0 and then setting the EOF marker on the file. In the Win32 API, for instance, you can do that with SetFilePointer() and SetEndOfFile().

c++ overwrite already opened file

I am opening a file with ifstream to check if it exists. Then I close it and open it with ofstream to write to it, and I think setting ios::trunc flag allows me to overwrite it.
However I'd like the ability to keep the file open if it exists, but I used an ifstream to open it so does that mean I can't write to the file till I close and re-open using fstream or ofstream? I didn't use fstream to begin with because that wouldn't tell me if the file was already there or not.
Just open a read-write fstream on the file. You can test if the file previously existed (and was non-empty) by seeking to the end and seeing if you're at a non-zero offset. If so, the file existed, and you can do whatever with it. If not, the file didn't exist or was empty. Assuming you don't need to distinguish between those two cases, you can then proceed as if it did not exist.
For example:
// Error checking omitted for expository purposes
std::fstream f("file.txt", std::ios::in | std::ios::out);
f.seekg(0, std::ios::end)
bool didFileExist = (f.tellg() > 0);
f.seekg(0, std::ios::beg);
// Now use the file in read-write mode. If didFileExist is true, then the
// file previously existed (and has not yet been modified)
The setting ios::trunc erases previous contents of the file.
Try opening the file without this setting; with only the 'write' setting.
this is touching very serios problem - race conditions - what if somebody manages to do something with this file between closing and reopening? unfortunately iostream does not provide any means of resolving that issue - you can use cstdio FILE. If you want to turncate file if exists or create new one if not use fopen(name, "w"). If you want to turncate file if it exists or fail otherwise, then it seems standard library has nothing to offer, and you should go to other libraries or platform specific functions like OpenFile in windows.h

fstream replace portion of a file

When I do
fstream someFile("something.dat", ios::binary|ios::out);
someFile.seekp(someLocation, ios::beg);
someFile.write(someData, 100);
It seems to replace the entire file with those 100 bytes instead of replacing only the appropriate 100 bytes, as if I had specified ios::trunc. Is there a portable way to not have it truncate the file?
Edit: adding ios::in seems to do the trick, by why is this required, and is that standard behavior?
Edit #2: I am not trying to append to the existing file. I need to replace the 100 bytes while leaving the rest unaffected.
You want the append flag, ios::app, if you want to write at the end of the file.
To do it somewhere arbitrarily in the middle of the file, you need to seek to the right place. You CAN do this by opening the file for in and out, but if I were you I'd create a temp file, copy input up to mark, write your new data, copy the rest to EOF, close the files and replace the previous version with the temp file. This is called a "Master File update".
AFAIR ios::out only specifies the file is for output and ios:binary only specifies the files is binary. The default behaviour for a stream is to create a new file and overwrite the old file. If you want to modify an existing file you must open the file with the ios::app flag.
ATM I cannot check my references so be sure to double check, but I felieve that is accurate.
Since the file already exists open it in 'read+write' mode and then do seekp. I think it will work.
fstream someFile("something.dat", ios::binary|ios::out|ios::in);
someFile.seekp(someLocation, ios::beg);
someFile.write(someData, 100);
The ios:in mask tells the file pointer to position at the beginning of the file so it can start reading in from the start. But, you may want to use fseek to set the file pointer at the beginning of the file.