Merge pull request #4634 from khellang/copy-to-async-buffer-size
Added CopyToAsync overload using default buffer size
This commit is contained in:
Коммит
a410be2def
|
@ -95,36 +95,7 @@ namespace System.IO
|
|||
|
||||
public Task CopyToAsync(Stream destination)
|
||||
{
|
||||
int bufferSize = DefaultCopyBufferSize;
|
||||
|
||||
if (CanSeek)
|
||||
{
|
||||
long length = Length;
|
||||
long position = Position;
|
||||
if (length <= position) // Handles negative overflows
|
||||
{
|
||||
// If we go down this branch, it means there are
|
||||
// no bytes left in this stream.
|
||||
|
||||
// Ideally we would just return Task.CompletedTask here,
|
||||
// but CopyToAsync(Stream, int, CancellationToken) was already
|
||||
// virtual at the time this optimization was introduced. So
|
||||
// if it does things like argument validation (checking if destination
|
||||
// is null and throwing an exception), then await fooStream.CopyToAsync(null)
|
||||
// would no longer throw if there were no bytes left. On the other hand,
|
||||
// we also can't roll our own argument validation and return Task.CompletedTask,
|
||||
// because it would be a breaking change if the stream's override didn't throw before,
|
||||
// or in a different order. So for simplicity, we just set the bufferSize to 1
|
||||
// (not 0 since the default implementation throws for 0) and forward to the virtual method.
|
||||
bufferSize = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
long remaining = length - position;
|
||||
if (remaining > 0) // In the case of a positive overflow, stick to the default size
|
||||
bufferSize = (int)Math.Min(bufferSize, remaining);
|
||||
}
|
||||
}
|
||||
int bufferSize = GetCopyBufferSize();
|
||||
|
||||
return CopyToAsync(destination, bufferSize);
|
||||
}
|
||||
|
@ -134,6 +105,13 @@ namespace System.IO
|
|||
return CopyToAsync(destination, bufferSize, CancellationToken.None);
|
||||
}
|
||||
|
||||
public Task CopyToAsync(Stream destination, CancellationToken cancellationToken)
|
||||
{
|
||||
int bufferSize = GetCopyBufferSize();
|
||||
|
||||
return CopyToAsync(destination, bufferSize, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
|
||||
{
|
||||
StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
|
||||
|
@ -162,26 +140,7 @@ namespace System.IO
|
|||
// the current position.
|
||||
public void CopyTo(Stream destination)
|
||||
{
|
||||
int bufferSize = DefaultCopyBufferSize;
|
||||
|
||||
if (CanSeek)
|
||||
{
|
||||
long length = Length;
|
||||
long position = Position;
|
||||
if (length <= position) // Handles negative overflows
|
||||
{
|
||||
// No bytes left in stream
|
||||
// Call the other overload with a bufferSize of 1,
|
||||
// in case it's made virtual in the future
|
||||
bufferSize = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
long remaining = length - position;
|
||||
if (remaining > 0) // In the case of a positive overflow, stick to the default size
|
||||
bufferSize = (int)Math.Min(bufferSize, remaining);
|
||||
}
|
||||
}
|
||||
int bufferSize = GetCopyBufferSize();
|
||||
|
||||
CopyTo(destination, bufferSize);
|
||||
}
|
||||
|
@ -198,6 +157,36 @@ namespace System.IO
|
|||
}
|
||||
}
|
||||
|
||||
private int GetCopyBufferSize()
|
||||
{
|
||||
int bufferSize = DefaultCopyBufferSize;
|
||||
|
||||
if (CanSeek)
|
||||
{
|
||||
long length = Length;
|
||||
long position = Position;
|
||||
if (length <= position) // Handles negative overflows
|
||||
{
|
||||
// There are no bytes left in the stream to copy.
|
||||
// However, because CopyTo{Async} is virtual, we need to
|
||||
// ensure that any override is still invoked to provide its
|
||||
// own validation, so we use the smallest legal buffer size here.
|
||||
bufferSize = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
long remaining = length - position;
|
||||
if (remaining > 0)
|
||||
{
|
||||
// In the case of a positive overflow, stick to the default size
|
||||
bufferSize = (int)Math.Min(bufferSize, remaining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
Dispose(true);
|
||||
|
|
Загрузка…
Ссылка в новой задаче