超大文件处理——大文件断点续传源码-下载大文件卡死服务器—星辰大文化术——未来之窗超算中心
大文件断点下载必要性
- 应对网络中断:网络环境不稳定是常见问题,下载大文件时可能会因网络波动、信号中断等原因导致下载过程意外终止。如果没有断点下载功能,一旦中断就需要从头开始下载,这会浪费大量时间和网络流量。而断点下载可以记录已下载的部分,在网络恢复后从断点处继续下载,避免了重复下载已完成的部分,提高了下载效率。
- 节省时间和成本:大文件的下载往往需要较长时间,使用断点下载可以将下载过程分成多个阶段。用户可以在网络状况较好时进行下载,遇到网络不佳或其他紧急情况时暂停,待条件改善后再继续,灵活安排下载时间,有效利用碎片化时间,同时也节省了因重复下载而可能产生的额外网络费用。
- 提高系统稳定性:一次性将大文件全部加载到内存或进行长时间连续下载,可能会对设备的内存、硬盘等硬件资源造成较大压力,甚至导致系统卡顿、死机等问题。断点下载通过分块逐步下载,可以减轻系统在下载过程中的负担,降低对系统资源的占用,提高系统的稳定性和响应能力。
- 支持意外中断恢复:除网络中断外,设备突然断电、死机或用户误操作等意外情况也可能导致下载中断。断点下载功能能够在这些情况发生后,让用户无需重新开始下载,最大程度地减少了意外事件对下载任务的影响,保障了大文件下载的最终完成
C# 和 PHP 实现大文件断点下载的代码
using System;
using System.IO;
using System.Net;
using System.Web;public class DownloadHandler
{public void HandleDownload(HttpContext context, string filePath){if (!File.Exists(filePath)){context.Response.StatusCode = 404;return;}long fileLength = new FileInfo(filePath).Length;long startByte = 0;long endByte = fileLength - 1;int bufferSize = 10240;if (context.Request.Headers["Range"] != null){context.Response.StatusCode = 206;string range = context.Request.Headers["Range"].Replace("bytes=", "");string[] ranges = range.Split('-');if (ranges.Length > 0 && !string.IsNullOrEmpty(ranges[0])){startByte = long.Parse(ranges[0]);}if (ranges.Length > 1 && !string.IsNullOrEmpty(ranges[1])){endByte = long.Parse(ranges[1]);}}long contentLength = endByte - startByte + 1;context.Response.Clear();context.Response.ContentType = "application/octet-stream";context.Response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(filePath));context.Response.AddHeader("Content-Length", contentLength.ToString());context.Response.AddHeader("Content-Range", $"bytes {startByte}-{endByte}/{fileLength}");context.Response.AddHeader("Accept-Ranges", "bytes");using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)){fs.Seek(startByte, SeekOrigin.Begin);byte[] buffer = new byte[bufferSize];int bytesRead;while (contentLength > 0 && (bytesRead = fs.Read(buffer, 0, (int)Math.Min(bufferSize, contentLength))) > 0){context.Response.OutputStream.Write(buffer, 0, bytesRead);contentLength -= bytesRead;}}context.Response.End();}
}
<?php
$file = 'your_file_path'; // 替换为实际文件路径
if (!file_exists($file)) {header("HTTP/1.1 404 Not Found");exit;
}$filesize = filesize($file);
$start = 0;
$end = $filesize - 1;if (isset($_SERVER['HTTP_RANGE'])) {header("HTTP/1.1 206 Partial Content");$range = substr($_SERVER['HTTP_RANGE'], strpos($_SERVER['HTTP_RANGE'], '=') + 1);$range = explode('-', $range);if (isset($range[0]) && $range[0] != '') {$start = intval($range[0]);}if (isset($range[1]) && $range[1] != '') {$end = intval($range[1]);}
}$contentLength = $end - $start + 1;header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . basename($file));
header("Content-Length: $contentLength");
header("Content-Range: bytes $start-$end/$filesize");
header("Accept-Ranges: bytes");$handle = fopen($file, 'rb');
fseek($handle, $start);
while (!feof($handle) && ($contentLength > 0)) {$readSize = ($contentLength > 8192) ? 8192 : $contentLength;$buffer = fread($handle, $readSize);echo $buffer;$contentLength -= $readSize;flush();
}
fclose($handle);
?>
更多源码 https://mp.weixin.qq.com/s/kZrP_saz6g58t5FQsCPrwg