System.IO.FileStream.Seek C# (CSharp) Method

Seek() public method

public Seek ( long offset, SeekOrigin origin ) : long
offset long
origin SeekOrigin
return long
        public override long Seek(long offset, SeekOrigin origin)
        {
            if (origin < SeekOrigin.Begin || origin > SeekOrigin.End)
                throw new ArgumentException(SR.Argument_InvalidSeekOrigin, nameof(origin));
            if (_fileHandle.IsClosed) throw Error.GetFileNotOpen();
            if (!CanSeek) throw Error.GetSeekNotSupported();

            Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength), "We're either reading or writing, but not both.");

            // If we've got bytes in our buffer to write, write them out.
            // If we've read in and consumed some bytes, we'll have to adjust
            // our seek positions ONLY IF we're seeking relative to the current
            // position in the stream.  This simulates doing a seek to the new
            // position, then a read for the number of bytes we have in our buffer.
            if (_writePos > 0)
            {
                FlushWriteBuffer();
            }
            else if (origin == SeekOrigin.Current)
            {
                // Don't call FlushRead here, which would have caused an infinite
                // loop.  Simply adjust the seek origin.  This isn't necessary
                // if we're seeking relative to the beginning or end of the stream.
                offset -= (_readLength - _readPos);
            }
            _readPos = _readLength = 0;

            // Verify that internal position is in sync with the handle
            VerifyOSHandlePosition();

            long oldPos = _filePosition + (_readPos - _readLength);
            long pos = SeekCore(offset, origin);

            // Prevent users from overwriting data in a file that was opened in
            // append mode.
            if (_appendStart != -1 && pos < _appendStart)
            {
                SeekCore(oldPos, SeekOrigin.Begin);
                throw new IOException(SR.IO_SeekAppendOverwrite);
            }

            // We now must update the read buffer.  We can in some cases simply
            // update _readPos within the buffer, copy around the buffer so our 
            // Position property is still correct, and avoid having to do more 
            // reads from the disk.  Otherwise, discard the buffer's contents.
            if (_readLength > 0)
            {
                // We can optimize the following condition:
                // oldPos - _readPos <= pos < oldPos + _readLen - _readPos
                if (oldPos == pos)
                {
                    if (_readPos > 0)
                    {
                        //Console.WriteLine("Seek: seeked for 0, adjusting buffer back by: "+_readPos+"  _readLen: "+_readLen);
                        Buffer.BlockCopy(GetBuffer(), _readPos, GetBuffer(), 0, _readLength - _readPos);
                        _readLength -= _readPos;
                        _readPos = 0;
                    }
                    // If we still have buffered data, we must update the stream's 
                    // position so our Position property is correct.
                    if (_readLength > 0)
                        SeekCore(_readLength, SeekOrigin.Current);
                }
                else if (oldPos - _readPos < pos && pos < oldPos + _readLength - _readPos)
                {
                    int diff = (int)(pos - oldPos);
                    //Console.WriteLine("Seek: diff was "+diff+", readpos was "+_readPos+"  adjusting buffer - shrinking by "+ (_readPos + diff));
                    Buffer.BlockCopy(GetBuffer(), _readPos + diff, GetBuffer(), 0, _readLength - (_readPos + diff));
                    _readLength -= (_readPos + diff);
                    _readPos = 0;
                    if (_readLength > 0)
                        SeekCore(_readLength, SeekOrigin.Current);
                }
                else
                {
                    // Lose the read buffer.
                    _readPos = 0;
                    _readLength = 0;
                }
                Debug.Assert(_readLength >= 0 && _readPos <= _readLength, "_readLen should be nonnegative, and _readPos should be less than or equal _readLen");
                Debug.Assert(pos == Position, "Seek optimization: pos != Position!  Buffer math was mangled.");
            }
            return pos;
        }

Usage Example

Example #1
1
 public void Load(BinaryReader br, FileStream fs)
 {
     Offset = br.ReadInt32();
     Offset += 16;
     FrameCount = br.ReadInt32();
     MipWidth = br.ReadInt32();
     MipHeight = br.ReadInt32();
     StartX = br.ReadInt32();
     StartY = br.ReadInt32();
     TileCount = br.ReadUInt16();
     TotalCount = br.ReadUInt16();
     CellWidth = br.ReadUInt16();
     CellHeight = br.ReadUInt16();
     Frames = new EanFrame[TotalCount];
     long curPos = fs.Position;
     fs.Seek((long)Offset, SeekOrigin.Begin);
     for (int i = 0; i < TotalCount; i++)
     {
         Frames[i].X = br.ReadUInt16();
         Frames[i].Y = br.ReadUInt16();
         Frames[i].Width = br.ReadUInt16();
         Frames[i].Height = br.ReadUInt16();
     }
     fs.Seek((long)curPos, SeekOrigin.Begin);
 }
All Usage Examples Of System.IO.FileStream::Seek