This is probably a silly question. but of the two following ideas, which is conceptually correct when dealing with streams:
1) position is between characters
(pos0)byte0(pos1)byte1(pos2)byte2
2) position is on the character
(pos0/byte0)(pos1/byte1)(pos2/byte2)
thanks
The position is before the byte you read. If the position is 0 and your read one byte, you've read the first byte. If you set the position to the stream size, you can't read anything since there is nothing behind - you just could append something to file.
Related
I read byte by byte in FileStream. I use ReadByte.
I always need to check next byte. I would like to be able, if I read a certain byte, to go back one byte.
The reason is that when I meet this byte, I need to pass the FileStream to another function, but it needs to read it at this specific previous position (back one byte).
How can I achieve this?
Indeed I searched https://www.bing.com/search?q=c%23+change+position+to+previous+stream+site%3astackoverflow.com but all questions suggest to use Seek(offset, Beginning). Some user suggested duplicate which shows how to use .Seek(0, SeekOrigin.Begin); - that definitely what I want. I need to seek to current position (for which I found plausible method be searching for "C# filestream position" - FileStream.Position) decreased by one.
There is the Seek method to set the stream to a given position. You can get the current position of the stream with the Position property.
It should something like this then:
fileStream.Seek(filestream.Position - 1, SeekOrigin.Begin);
I have trouble to understand the word "Position of a stream". My question is somehow related to the concept of the stream method Seek(); it is kind confusing to me what this method does, they say its purpose is to set the position of the stream to a given value but yet its name describes the seek operation not set operation. Does anyone understand clearly what these two words are for and how they work together? Thanx
Think about a file as a sequence of bytes, and a stream as a view over that sequence, with a cursor marking the current position - so as you read data, the cursor is advanced. The Position property is simply the position of that cursor. So when you open a stream it's typically at 0, and as you read it increases. For seekable streams, you can "rewind" to the start of the stream with
stream.Position = 0;
or maybe skip 10 bytes using:
stream.Position += 10;
etc.
A stream is basically a sequence of bytes - the position is the point in the sequence that the stream is in.
The point of Seek is to "jump" to a location in the stream - a specific index (aka Position), similar to seeks done in a hard drive. With Seek you can specify an offset to start seeking from, so how many bytes to "jump".
The following 2 statements do exactly the same:
s.Position = 100;
s.Seek(100, SeekOrigin.Begin);
And they both determine the position (as a bytecount) where the next Read or Write will occur.
The Seek() name is very ancient.
I actually agree that, at first glance, Seek is not the best name for what it does. SeekAndSet or SeekAndMove would make more sense to me because that is what the method does - it seeks the position you want in the stream and sets the cursor to that position.
However, when you think of Seek in Computer Science terms in relation to hard disk drives it becomes obvious what this method does. It seeks and moves to the position.
I want to convert an image file to a string. The following works:
MemoryStream ms = new MemoryStream();
Image1.Save(ms, ImageFormat.Jpeg);
byte[] picture = ms.ToArray();
string formmattedPic = Convert.ToBase64String(picture);
However, when saving this to a XmlWriter, it takes ages before it's saved(20secs for a 26k image file). Is there a way to speed this action up?
Thanks,
Raks
There are three points where you are doing large operations needlessly:
Getting the stream's bytes
Converting it to Base64
Writing it to the XmlWriter.
Instead. First call Length and GetBuffer. This let's you operate upon the stream's buffer directly. (Do flush it first though).
Then, implement base-64 yourself. It's relatively simple as you take groups of 3 bytes, do some bit-twiddling to get the index into the character it'll be converted to, and then output that character. At the very end you add some = symbols according to how many bytes where in the last block sent (= for one remainder byte, == for two remainder bytes and none if there were no partial blocks).
Do this writting into a char buffer (a char[]). The most efficient size is a matter for experimentation but I'd start with 2048 characters. When you've filled the buffer, call XmlWriter.WriteRaw on it, and then start writing back at index 0 again.
This way, you're doing less allocations, and you're started on the output from the moment you've got your image loaded into the memory stream. Generally, this should result in better throughput.
Could anyone please explain to me the differences, if any?
I tried to Google it but couldn't find much information. Maybe I didn't use correct keywords.
Any insight would be greatly appreciated.
stream.Seek(x, SeekOrigin.Begin); and stream.Position = x; both result in the stream position being set to x. The difference is that the Position setter unconditionally discards any read buffer, while the Seek method attempts to retain the part of the buffer that is still relevant to the new position.
You'll have to test, which one is faster for your scenario, but there's definitely a performance difference and neither is faster in all cases. I really wonder why this difference isn't documented.
In your example there is no difference.
The actual difference between Stream.Position and Stream.Seek is that Position uses an absolute offset whereas Seek uses an offset relative to the origin specified by the second argument.
As far as I can tell, at least for this specific case, nothing.
Both method Seek() and property Position require CanSeek to be true so from what I see it's up to the implementer.
Seek is really there to allow searching from specified locations (SeekOrigins) to an offset (the examples given on MSDN are somewhat convoluted but representative of the purpose: http://msdn.microsoft.com/en-us/library/system.io.filestream.seek.aspx).
Position is absolute and is obviously not meant for searching.
The case you mentioned just happens to be equivalent.
Personally, I'd use .Position = 0 to move to the beginning of the stream as that reads cleaner to me than "Seek using the beginning of the file as an origin and move this 0 offset of bytes."
does anyone know how i can retrieve the frame dimension of a mpeg4 video (non h264, i.e. Mpeg4 Part 2) from the raw video bitstream?
i´m currently writing a custom media source for windows media foundation, i have to provide a mediatype which needs the frame size. it doesn´t work without it.
any ideas?
thanks
I am not getting you. Are you trying to know the width and the height of the video being streamed? If so (and I guess that it is the "dimension" you are looking for) heres how:
Parse the stream for this integer 000001B0(hex) its always the first thing you get streamed. If not, see the SDP of the stream (if you have any, and search for config= field, and there it is... only now it is a Base16 string!
Read all the bytes until you get to the integer 000001B6(hex)
You should get something like this (hex): 000001B0F5000001B5891300000100000001200086C40FA28 A021E0A2
This is the "stream configuration header" or frame or whatever, exact name is Video Object Sequence. It holds all the info a decoder would need to decode the video stream.
Read the last 4 bytes (in my example they are separated by one space -- A021E0A2)
Now observe these bytes as one 32-bit unsigned integer...
To get width read the first 8 bits, and then multiply what you get with 4
Skip next 7 bits
To get height read next 9 bits
In pseudo code:
WIDTH = readBitsUnsigned(array, 8) * 4;
readBitsUnsigned(array, 7);
HEIGHT = readBitsUnsigned(array, 9);
There you go... width and height. (: