public override void Write(byte[] buffer, int offset, int count) { CheckDisposed(); var done = false; long left = count; long current = offset; if (_needsRead) { SeekInternal(_lastPosition, SeekOrigin.Begin); NativeFile.Read(_handle, _writeBuffer, 0, (int)_blockSize); SeekInternal(_lastPosition, SeekOrigin.Begin); _needsRead = false; } while (!done) { _needsFlush = true; if (_bufferedCount + left < _writeBufferSize) { CopyBuffer(buffer, current, left); done = true; current += left; } else { var toFill = _writeBufferSize - _bufferedCount; CopyBuffer(buffer, current, toFill); Flush(); left -= toFill; current += toFill; done = left == 0; } } }
public static UnbufferedFileStream Create(string path, FileMode mode, FileAccess acc, FileShare share, bool sequential, int internalWriteBufferSize, int internalReadBufferSize, bool writeThrough, uint minBlockSize) { var blockSize = NativeFile.GetDriveSectorSize(path); blockSize = blockSize > minBlockSize ? blockSize : minBlockSize; if (internalWriteBufferSize % blockSize != 0) { throw new Exception("write buffer size must be aligned to block size of " + blockSize + " bytes"); } if (internalReadBufferSize % blockSize != 0) { throw new Exception("read buffer size must be aligned to block size of " + blockSize + " bytes"); } var handle = NativeFile.CreateUnbufferedRW(path, acc, share, mode, writeThrough); return(new UnbufferedFileStream(handle, blockSize, internalWriteBufferSize, internalReadBufferSize)); }
public override void SetLength(long value) { CheckDisposed(); var aligned = GetLowestAlignment(value); aligned = aligned == value ? aligned : aligned + _blockSize; NativeFile.SetFileSize(_handle, aligned); Seek(0, SeekOrigin.Begin); }
public override int Read(byte[] buffer, int offset, int count) { CheckDisposed(); if (offset < 0 || buffer.Length < offset) { throw new ArgumentException("offset"); } if (count < 0 || buffer.Length < count) { throw new ArgumentException("offset"); } if (offset + count > buffer.Length) { throw new ArgumentException("offset + count must be less than size of array"); } var position = GetLowestAlignment(Position); var roffset = (int)(Position - position); var bytesRead = _readBufferSize; if (_readLocation + _readBufferSize <= position || _readLocation > position || _readLocation == 0) { SeekInternal(position); bytesRead = NativeFile.Read(_handle, _readBuffer, 0, _readBufferSize); _readLocation = position; } else if (_readLocation != position) { roffset += (int)(position - _readLocation); } var bytesAvailable = bytesRead - roffset; if (bytesAvailable <= 0) { return(0); } var toCopy = count > bytesAvailable ? bytesAvailable : count; MemCopy(_readBuffer, roffset, buffer, offset, toCopy); _bufferedCount += toCopy; if (count - toCopy == 0) { return(toCopy); } return(toCopy + Read(buffer, offset + toCopy, count - toCopy)); }
public override long Seek(long offset, SeekOrigin origin) { CheckDisposed(); if (origin == SeekOrigin.Current) { throw new NotImplementedException("only supports seek origin begin/end"); } if (origin == SeekOrigin.End) { offset = Length + offset; } var aligned = GetLowestAlignment(offset); var left = (int)(offset - aligned); Flush(); _bufferedCount = left; _aligned = aligned == left; _lastPosition = aligned; SeekInternal(aligned); NativeFile.Read(_handle, _writeBuffer, 0, (int)_blockSize); SeekInternal(aligned); return(offset); }
private void InternalWrite(byte *buffer, uint count) { var written = 0; NativeFile.Write(_handle, buffer, count, ref written); }
private void SeekInternal(long positionAligned) { NativeFile.Seek(_handle, positionAligned, SeekOrigin.Begin); }