[Development] QFile: writing via a temporary file

João Abecasis joao.abecasis at nokia.com
Tue Jan 10 13:43:29 CET 2012


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.

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.

> 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.

> I think if we think of the tempfile as "an internal buffering mechanism" rather 
> than "a second file exposed via the qfile api", then all these issues of "which 
> file is this about now" don't happen at all.
> 
>> 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?)

If readers only care about fully written versions, they already need a separate object. And whatever we do they won't magically know that a new version has been written to disk. Most likely they have to discard caches and read/load again from disk.

>>> The other question is, would one have to call commit/rollback
>>> explicitely, or should QFile::close() (and the dtor) do the
>>> committing?
>> 
>> I think commit should require explicit action, for instance, by
>> explicitly calling close(). I don't like having the destructor
>> automatically commit (even if it calls close) though.
> 
> QFile's destructor has always called close(), that's in everyone's mind, so I 
> don't think we want explicit and implicit close to work differently, that would 
> be very confusing.

I'm leaning towards not overloading close's meaning. In particular if you intend this to interact with legacy code bases.

> 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 ;-)

[snip, discussion ongoing in separate e-mails in this thread]

>> What happens to writes happening after a commit, though?
> 
> This problem doesn't happen if commit == close(). You can't write after 
> closing, that much is obvious to everyone.

This goes with my idea that closed QIODevices should not exist...

Cheers,


João




More information about the Development mailing list