Stream.Seek(0, SeekOrigin.Begin) or Position = 0
Asked Answered
L

3

227

When you need to reset a stream to beginning (e.g. MemoryStream) is it best practice to use

stream.Seek(0, SeekOrigin.Begin);

or

stream.Position = 0;

I've seen both work fine, but wondered if one was more correct than the other?

Luiseluiza answered 30/8, 2011 at 5:7 Comment(3)
If it is to return the contents of the memory stream, ToArray works regardless of positionZachery
Answer: The one being most readable.Kimon
I personally prefer stream.Position = 0; but I have to agree with @jgauffin, just choose the most readable, both solutions work fine.Flam
A
210

Use Position when setting an absolute position and Seek when setting a relative position. Both are provided for convenience so you can choose one that fits the style and readability of your code. Accessing Position requires the stream be seekable so they're safely interchangeable.

Averell answered 30/8, 2011 at 5:22 Comment(3)
I use the property even for relative positions: stream.Position += 10; seems pretty readable to me.Neurogram
Is there a speed difference between using SeekOrigin.Begin and SeekOrigin.Current?Edgardoedge
@Edgardoedge "Return Value: The new position within the stream, calculated by combining the initial reference point and the offset.". So the combining costs a little bit more than just setting the position directly. Practically it means nothing but nit-picking. )))Amalgamation
A
26

You can look at the source code for both methods to find out:

The cost is almost identical (3 ifs and some arithmetics). However, this is only true for jumping to absolute offsets like Position = 0 and not relative offsets like Position += 0, in which case Seek seems slightly better.

However, you should keep in mind that we are talking about performance of a handful of integer arithmetics and if checks, that's like not even accurately measureable with benchmarking methods. Like others already pointed out, there is no significant/detectable difference.

Aconcagua answered 6/4, 2018 at 20:49 Comment(1)
MemoryStream does just arithmetics, because it is basically just a byte array. Is this true even for other seekable streams? I would be interested in how this works in FileStream. I suspect that even there, the difference is very small and it boils down to a single syscall setting the position, but I am not sure whether the current position is actually kept in memory. If it is not, getting it requires another syscall, unlike when using the Seek method.Crake
S
7

If you are working with files (eg: with the FileStream class) it seems Seek(0, SeekOrigin.Begin) is able to keep internal buffer (when possible) while Position=0 will always discard it.

Sinh answered 24/3, 2022 at 1:44 Comment(2)
You are referencing .NET Framework sources. Does this hold for current .NET (.NET 8), too?Crake
It seems to be different. Position setter defers the call to _strategy.Position. FileStream use BufferedFileStreamStrategy as strategy and that one simply call Seek(value, SeekOrigin.Begin). I would say buffer is preserved (to be tested).Sinh

© 2022 - 2024 — McMap. All rights reserved.