[英]FileStream: is buffer automatically flushed when full?
In a WCF service I have a FileStream
that is supposed to create a huge file. 在WCF服务中,我有一个
FileStream
,它应该创建一个大文件。
A procedure within the WCF service regularly receives a chunk of bytes that must be written to the FileStream
. WCF服务中的过程定期接收必须写入
FileStream
大量字节。 The FileStream
uses the default buffer size. FileStream
使用默认的缓冲区大小。
My procedure receives bytes in chunks with the same size as the size of the FileStream's buffer, except maybe for the last chunk. 我的过程接收块中的字节,其大小与FileStream缓冲区的大小相同,但最后一个块除外。 The procedure writes the complete chunk to the FileStream.
该过程将完整的块写入FileStream。 Therefore after most writes the FileStream's buffer is expected to be full.
因此,在大多数写入之后,预期FileStream的缓冲区已满。
Question: Is a full buffer automatically flushed or should I Flush whenever I think that the buffer is full? 问:满缓冲区是否会自动刷新?或者每当我认为缓冲区已满时应该刷新吗?
If full buffers are automatically flushed then my Flush would do more harm than good, because it would Flush immediately after the buffer is already flushed. 如果自动刷新满了的缓冲区,那么我的Flush弊大于利,因为在缓冲区已经刷新后会立即进行Flush。
Code is as follows: 代码如下:
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
methods always call flush
for you according to the implementation 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.