/// <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();

            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);
            }
        }
Exemple #2
0
        public static async Task SendFile(HttpContext httpContext, string requestPath)
        {
            await using var fileStream = new FileStream(requestPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            GetTransferPosition(httpContext, fileStream.Length, out long startRange, out long endRange);
            fileStream.Position = startRange;
            var contentType = ContentType.DEFAULT.FromExtension(requestPath);

            // 7 * 24 Hour * 60 Min * 60 Sec = 604800 Sec;
            //httpContext.Response.Headers["Access-Control-Allow-Origin"] = "*";
            httpContext.Response.Headers["Date"] = DateTime.Now.ToString("r");
            //context.Response.Headers.Add("Last-Modified", File.GetLastWriteTime(requestPath).ToString("r"));
            httpContext.Response.Headers["Server"] = "HtcSharp";
            //context.Response.Headers.Add("Cache-Control", "max-age=604800");
            httpContext.Response.ContentType = contentType.ToValue();
            httpContext.Response.StatusCode  = 200;
            if (UseGzip(httpContext, fileStream.Length))
            {
                httpContext.Response.Headers["Content-Encoding"] = "gzip";
                await using var gzipStream = new GZipStream(httpContext.Response.Body, CompressionLevel.Fastest);
                await StreamCopyOperationInternal.CopyToAsync(fileStream, gzipStream, endRange, httpContext.RequestAborted);
            }
            else
            {
                httpContext.Response.ContentLength = endRange - startRange;
                await StreamCopyOperationInternal.CopyToAsync(fileStream, httpContext.Response.Body, endRange, httpContext.RequestAborted);
            }
        }
Exemple #3
0
 /// <summary>Asynchronously reads the given number of bytes from the source stream and writes them to another stream, using a specified buffer size.</summary>
 /// <returns>A task that represents the asynchronous copy operation.</returns>
 /// <param name="source">The stream from which the contents will be copied.</param>
 /// <param name="destination">The stream to which the contents of the current stream will be copied.</param>
 /// <param name="count">The count of bytes to be copied.</param>
 /// <param name="bufferSize">The size, in bytes, of the buffer. This value must be greater than zero. The default size is 4096.</param>
 /// <param name="cancel">The token to monitor for cancellation requests. The default value is <see cref="P:System.Threading.CancellationToken.None" />.</param>
 public static Task CopyToAsync(Stream source, Stream destination, long?count, int bufferSize, CancellationToken cancel)
 => StreamCopyOperationInternal.CopyToAsync(source, destination, count, bufferSize, cancel);