| File: SendFileFallback.cs | Web Access |
| Project: src\aspnetcore\src\Http\Http\src\Microsoft.AspNetCore.Http.csproj (Microsoft.AspNetCore.Http) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace Microsoft.AspNetCore.Http; /// <summary> /// Helper type that allows copying a file to a Stream. /// <para> /// This type is part of ASP.NET Core's infrastructure and should not used by application code. /// </para> /// </summary> public static class SendFileFallback { /// <summary> /// Copies the segment of the file to the destination stream. /// </summary> /// <param name="destination">The stream to write the file segment to.</param> /// <param name="filePath">The full disk path to the file.</param> /// <param name="offset">The offset in the file to start at.</param> /// <param name="count">The number of bytes to send, or null to send the remainder of the file.</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> used to abort the transmission.</param> /// <returns></returns> public static async Task SendFileAsync(Stream destination, string filePath, long offset, long? count, CancellationToken cancellationToken) { var fileInfo = new FileInfo(filePath); if (offset < 0 || offset > fileInfo.Length) { throw new ArgumentOutOfRangeException(nameof(offset), offset, string.Empty); } if (count.HasValue && (count.Value < 0 || count.Value > fileInfo.Length - offset)) { throw new ArgumentOutOfRangeException(nameof(count), count, string.Empty); } cancellationToken.ThrowIfCancellationRequested(); const int bufferSize = 1024 * 16; var fileStream = new FileStream( filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferSize: bufferSize, options: FileOptions.Asynchronous | FileOptions.SequentialScan); using (fileStream) { fileStream.Seek(offset, SeekOrigin.Begin); await StreamCopyOperationInternal.CopyToAsync(fileStream, destination, count, bufferSize, cancellationToken); } } }