示例#1
0
        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;
                }
            }
        }
示例#2
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));
        }
示例#3
0
        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);
        }
示例#4
0
        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));
        }
示例#5
0
        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);
        }
示例#6
0
        private void InternalWrite(byte *buffer, uint count)
        {
            var written = 0;

            NativeFile.Write(_handle, buffer, count, ref written);
        }
示例#7
0
 private void SeekInternal(long positionAligned)
 {
     NativeFile.Seek(_handle, positionAligned, SeekOrigin.Begin);
 }