簡體   English   中英

FileStream:緩沖區已滿時會自動刷新嗎?

[英]FileStream: is buffer automatically flushed when full?

在WCF服務中,我有一個FileStream ,它應該創建一個大文件。

WCF服務中的過程定期接收必須寫入FileStream大量字節。 FileStream使用默認的緩沖區大小。

我的過程接收塊中的字節,其大小與FileStream緩沖區的大小相同,但最后一個塊除外。 該過程將完整的塊寫入FileStream。 因此,在大多數寫入之后,預期FileStream的緩沖區已滿。

問:滿緩沖區是否會自動刷新?或者每當我認為緩沖區已滿時應該刷新嗎?

如果自動刷新滿了的緩沖區,那么我的Flush弊大於利,因為在緩沖區已經刷新后會立即進行Flush。

代碼如下:

async Task PersistData(byte[] receivedData)
{
    // write all bytes in one write to the FileStream:
    await stream.WriteAsync(receivedData, 0, receivedData.Length);

    // This will have filled the buffer to the brim.
    // Should I Flush or did the FileStream already Flush?
    await stream.FlushAsync();
}

WriteAsync方法始終根據實現為您調用flush

private FileStreamAsyncResult BeginWriteAsync(byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject)
        {
            Contract.Assert(_isAsync);

            if (!CanWrite) __Error.WriteNotSupported();

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

            if (_isPipe)
            {
                // Pipes are ----ed up, at least when you have 2 different pipes
                // that you want to use simultaneously.  When redirecting stdout
                // & stderr with the Process class, it's easy to deadlock your
                // parent & child processes when doing writes 4K at a time.  The
                // OS appears to use a 4K buffer internally.  If you write to a
                // pipe that is full, you will block until someone read from 
                // that pipe.  If you try reading from an empty pipe and 
                // FileStream's BeginRead blocks waiting for data to fill it's 
                // internal buffer, you will be blocked.  In a case where a child
                // process writes to stdout & stderr while a parent process tries
                // reading from both, you can easily get into a deadlock here.
                // To avoid this deadlock, don't buffer when doing async IO on
                // pipes.   
                Contract.Assert(_readPos == 0 && _readLen == 0, "FileStream must not have buffered data here!  Pipes should be unidirectional.");

                if (_writePos > 0)
                    FlushWrite(false);

                return BeginWriteCore(array, offset, numBytes, userCallback, stateObject);
            }

            // Handle buffering.
            if (_writePos == 0)
            {
                if (_readPos < _readLen) FlushRead();
                _readPos = 0;
                _readLen = 0;
            }

            int n = _bufferSize - _writePos;
            if (numBytes <= n)
            {
                if (_writePos == 0) _buffer = new byte[_bufferSize];
                Buffer.InternalBlockCopy(array, offset, _buffer, _writePos, numBytes);
                _writePos += numBytes;

                // Return a synchronous FileStreamAsyncResult
                return FileStreamAsyncResult.CreateBufferedReadResult(numBytes, userCallback, stateObject, true);
            }

            if (_writePos > 0)
                FlushWrite(false);

            return BeginWriteCore(array, offset, numBytes, userCallback, stateObject);
        }
#endif // FEATURE_ASYNC_IO

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM