在电子商务系统中,尤其是提供可下载产品的系统,跟踪下载状态至关重要。用户可能只有有限次数的下载权限,通常是一次。如果下载成功,系统应该更新记录,告知用户已经下载了文件或增加下载计数。对于失败的下载,用户应能够重新下载,或者下载计数应保持不变。本文将帮助跟踪此类下载状态。
在电子商务项目中,需要实现一个功能,可以跟踪下载的成功或失败。在寻找解决方案后,发现没有相关文章讨论类似问题。因此,在阅读了一篇关于分包传输文件的文章后,提出了这个解决方案。希望这能对遇到类似问题的其他人有所帮助。
代码包含了ASP.NET中文件下载的基本逻辑,不会向最终用户显示文件的位置。首先,创建一个System.IO.FileInfo对象,提供完整的文件路径,这将给文件长度。还创建了一个FileStream对象,它将被传递给BinaryReader对象,这将帮助读取数据为字节。然后使用Response对象来传输数据。
string filePath = Server.MapPath("~/ApplicationData/DownloadableProducts");
string _DownloadableProductFileName = "DownloadableProduct_FileName.pdf";
System.IO.FileInfo FileName = new System.IO.FileInfo(filePath + "\\" + _DownloadableProductFileName);
FileStream myFile = new FileStream(filePath + "\\" + _DownloadableProductFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
BinaryReader _BinaryReader = new BinaryReader(myFile);
long startBytes = 0;
string lastUpdateTiemStamp = File.GetLastWriteTimeUtc(filePath).ToString("r");
string _EncodedData = HttpUtility.UrlEncode(_DownloadableProductFileName, Encoding.UTF8) + lastUpdateTiemStamp;
Response.Clear();
Response.Buffer = false;
Response.AddHeader("Accept-Ranges", "bytes");
Response.AppendHeader("ETag", "\"" + _EncodedData + "\"");
Response.AppendHeader("Last-Modified", lastUpdateTiemStamp);
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment;filename=" + FileName.Name);
Response.AddHeader("Content-Length", (FileName.Length - startBytes).ToString());
Response.AddHeader("Connection", "Keep-Alive");
Response.ContentEncoding = Encoding.UTF8;
_BinaryReader.BaseStream.Seek(startBytes, SeekOrigin.Begin);
下载窗口没有返回响应,无论是下载完成还是中途取消,因此很难知道下载的状态。跟踪下载状态的基本逻辑是将文件分成更小的数据包(数据包的大小可以根据方便进行调整),并检查是否所有数据包都已传输。如果在文件传输过程中出现任何故障,总数据包数将与传输的数据包数进行比较。这种比较将决定下载的状态(成功/失败)。
对于非常小的文件,很难跟踪下载失败,因为数据包的数量会很少。如果文件大小超过10KB,跟踪将更有效。在下面的代码中,通过将总字节数除以1024来获得总数据包数,以保持数据包大小为1KB。为了逐个发送数据包,使用for循环。使用Response.BinaryWrite,一次发送1024字节的数据,这是通过BinaryReader读取的。
int maxCount = (int)Math.Ceiling((FileName.Length - startBytes + 0.0) / 1024);
for (int i = 0; i < maxCount && Response.IsClientConnected; i++) {
Response.BinaryWrite(_BinaryReader.ReadBytes(1024));
Respons.Flush();
}
if (i < maxCount)
return false;
return true;
_BinaryReader.Close();
myFile.Close();
然后比较传输的数据包数与通过将文件长度除以1024计算出的总数据包数。如果这两个参数相等,那么文件传输成功,所有数据包都已传输。如果传输的数据包数少于总数据包数,那表明有问题,传输没有完成。