[Development] QFile: writing via a temporary file

David Faure faure at kde.org
Thu Jan 19 19:33:30 CET 2012


On Tuesday 10 January 2012 13:43:29 =?ISO-8859-1?Q?Jo=E3o?= Abecasis wrote:
> On 6. jan. 2012, at 21.27, ext David Faure wrote:
> > On Friday 06 January 2012 11:41:05 =?ISO-8859-1?Q?Jo=E3o?= Abecasis wrote:
> >> I don't support putting this in QFile as has been suggested as, from my
> >> experience with it, this will open a can of worms in maintenance and
> >> subtle issues cropping up in user code such as the ones being discussed:
> >> what's fileName()?  Does it exists() before commit? What do remove() and
> >> rename(newName) do?
> > 
> > If we go towards the idea that the temp file is really internal (as the
> > idea of a mode flag would point to), then fileName() can keep being the
> > target file, exists() will only be true if it already existed before
> > starting to write.
> > 
> > If it didn't exist before, then f.open(); f.write(); f.exists() is very
> > fragile anyway, isn't it? It sounds like the result depends on whether OS
> > flushed it to disk or not... So this doesn't seem like a valid use case
> > anyway.
> If your argument that deriving or adding functionality to QFile is that
> we'll be able to use the transactional feature with old code, then we need
> to consider cases that previously were valid because there is code doing a
> lot of interesting things out there.

Well it's not like the feature will be enabled by default, either. Developers 
will still to activate it, and look at the actual code writing into the file.
Still, I feel we're discussing an impossible corner case here, checking 
exists() after open() and before write().

> Adding something that we know no one is using because it didn't exist before
> allows us to focus on the features and use cases we want to support.

Agreed.

> > When it comes to remove and rename, they are already documented to close
> > the file first, so this would finish the writing operation, and no
> > surprises will happen to the user calling them. No issue of "which file
> > is it about", there is only one file after close() anyway.
> 
> I'm coming to think that relying on close (explicit or implicit) to mean
> commit is a really bad idea. Particularly when interacting with "legacy"
> codebases that were not written with that assumption.

Unless QFile itself remembers that an error happened, see the other email I 
just sent, which I think interacts perfectly with "legacy" code bases (doing 
f.write(foo); f.write(bar);).

> >> I think we would be well served by an API that exposes a QIODevice
> >> interface plus additional interface for commit/rollback.
> > 
> > This represents more porting effort for the application developer.
> > I have seen it in KDE in the past, where having to manage one more object,
> > but only in writing mode, not in reading mode, and making sure to call
> > commit/rollback on it, was a lot of trouble, compared to the initial code
> > that was simply using a QFile for all that. Enabling a flag on that QFile
> > would have been soooo much easier.
> 
> If it's a QIODevice, it can handle reading and writing, but I'm not sure
> it's relevant in this context. Who are the readers and would they be
> reading a half-written version of the file? (Why?)

I never said anyone would care about a half-written file...

I meant that your loading and your saving code aren't symmetric. Instead of 
using QFile for both, you have to use a different class for saving. This 
creates difficulties in classes that want to share code between loading and 
saving (e.g. I had that in a zip handling class, which much like qfile, had a 
open(Mode) method).

> > When writing to a file, you normally don't have to confirm "yes I want to
> > commit my changes". So the safer use of a temp file shouldn't require
> > this either, others have convinced me in this thread.
> 
> Because "normally" you don't get the transaction guarantee we'll be getting
> with your feature and "normally" you're not throwing away a good complete
> copy of your thesis ;-)

Yes you are, when you're writing over it. And you're losing it, if the disk 
gets full while saving. Hence QFile::open(QIODevice::WriteOnly | 
QIODevice::Transactional) ;)

-- 
David Faure, faure at kde.org, http://www.davidfaure.fr
Sponsored by Nokia to work on KDE, incl. KDE Frameworks 5




More information about the Development mailing list