views:

281

answers:

4

In the past I've always used a FileStream object to write or rewrite an entire file after which I would immediately close the stream. However, now I'm working on a program in which I want to keep a FileStream open in order to allow the user to retain access to the file while they are working in between saves. ( See my previous question).

I'm using XmlSerializer to serialize my classes to a from and XML file. But now I'm keeping the FileStream open to be used to save (reserialized) my class instance later. Are there any special considerations I need to make if I'm reusing the same File Stream over and over again, versus using a new file stream? Do I need to reset the stream to the beginning between saves? If a later save is smaller in size than the previous save will the FileStream leave the remainder bytes from the old file, and thus create a corrupted file? Do I need to do something to clear the file so it will behave as if I'm writing an entirely new file each time?

+2  A: 

Your suspicion is correct - if you reset the position of an open file stream and write content that's smaller than what's already in the file, it will leave trailing data and result in a corrupt file (depending on your definition of "corrupt", of course).

If you want to overwrite the file, you really should close the stream when you're finished with it and create a new stream when you're ready to re-save.

I notice from your linked question that you are holding the file open in order to prevent other users from writing to it at the same time. This probably wouldn't be my choice, but if you are going to do that, then I think you can "clear" the file by invoking stream.SetLength(0) between successive saves.

Aaronaught
What would your choice be then? I don't want allow two users to open the file at the same time thinking they both have write access and each overwriting the other's saves?
Eric Anastas
One of the more common answers is to create a zero-length "lock file". This can be combined with holding a `FileStream` open indefinitely, of course, but a lot of apps opt for only the lock file because it can be overridden if necessary. I guess it depends on the nature of your app and sharing environment - maybe it really is the best option.
Aaronaught
Set-length(0) seems to do what I'm trying to do.
Eric Anastas
A: 

Based on your question I think you'd be better served closing/re-opening the underlying file. You don't seem to be doing anything other than writing the whole file. The value you can add by re-writing Open/Close/Flush/Seek will be next to 0. Concentrate on your business problem.

No Refunds No Returns
Yes I'm just rewriting the entire file. So would you just suggest keeping the stream open to lock out access to the file, and then quickly closing and reopening the stream when I need to write the file again?
Eric Anastas
Why do you want to keep the file open? What business purpose does it serve?
No Refunds No Returns
+2  A: 

Another option might be to use SetLength(0) to truncate the file before you start rewriting it.

Andrew
A: 

There are various ways to do this; if you are re-opening the file, perhaps set it to truncate:

using(var file = new FileStream(path, FileMode.Truncate)) {
    // write
}

If you are overwriting the file while already open, then just trim it after writing:

file.SetLength(file.Position); // assumes we're at the new end

I would try to avoid delete/recreate, since this loses any ACLs etc.

Marc Gravell