Hey folks, I need to truncate a file to a larger size. The problem is, the struct I'm using defines the object-to-be-resized as a type
T: Read + Write + Seek which is in principle what a file is, but crucially, none of these traits provide a
set_len method. This exists on
File rather than one of it's many implemented traits.
My question is how can I cause the buffer to expand with only those three traits?
Truncate only makes sense when shrinking. If you want to make the file bigger, you need to give it data. So just seek to the end and then write however many bytes you want to expand it by.
I feel this highlights that
File isn't the union of those three disjoint sets of abilities (traits). From that vantage point,
set_len is an ability of
Seek + Write and thus would need it's own trait in order to have its own method in generic context.
(Seeking to the end and appending
0s isn't necessarily the same thing, as some
File implementations may have optimized ways to 0-extend a file (sparse files).)
Well, you're totally able to seek past the end of a file and try to write to it. I would guess the standard library
File would error, but the traits wouldn't mind.
Meaning, you could write an
impl Read + Write + Seek that wraps the standard library
File, but calls
set_len instead of returning an error.
I took the OP to mean that they're stuck in the context of having a
T: Read + Write + Seek and were thus out of luck without specialization. If I'm wrong and they're in the context of having ahold of the
File non-generically too, I agree a new type would open up a way to call
Interesting question on what "seek past the end and write" does though... the implementations of those traits are tragically underdocumented (though honestly if they were properly documented they'd probably just say "we do whatever your OS does" at best).
Writing a single byte (while taking more care than that quick experiment did) may in fact get you some (but not all) of the optimized behavior.
(Note that appending won't work for all
T: Read + Write + Seek either, e.g.
Thanks to everyone's input! I was able to get around my problem by using the behaviour of files (which is to expand if it doesn't fit) and define all other types to be invalid if they don't do this, which would result in an error, which can then be propagated.
It's not a nice solution but ultimately it's the one which gives the most well-defined behaviour, which we rustaceans love.....