دانلود فایل با قابلیت Resume

پنجشنبه 15 مرداد 1394

در این مقاله قصد داریم نحوه دانلود فایل با قابلیت دانلود ادامه فایل در زمان دیگری را بررسی کنیم .

این کار را میتوانید توسط کلاس زیر انجام دهید

 

using System;
using System.IO;
using System.Web;
using System.Collections;
using System.Data;
using System.Net;
using System.Security.Cryptography;

namespace SoftProjects.WebPresentation.Utility
{
	/// <summary>
	/// Orginal class name is "ZIPHandler" in VB.Net
	/// http://www.devx.com
	/// 
	/// Optimization and convertion by SalarSoft
	/// http://salarsoft.somee.com 
	/// 
	/// Last update: 2008-2-12
	/// </summary>
	public class ResumeDownload : IDisposable
	{
		const string MULTIPART_BOUNDARY = "<q1w2e3r4t5y6u7i8o9p0>";
		const string MULTIPART_CONTENTTYPE = "multipart/byteranges; boundary=" + MULTIPART_BOUNDARY;

		//Response.AddHeader("Content-Disposition","attachment; filename=" + Path.GetFileName(fUrl));
		const string HTTP_HEADER_Content_Disposition = "Content-Disposition";

		const string HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges";
		const string HTTP_HEADER_ACCEPT_RANGES_BYTES = "bytes";
		const string HTTP_HEADER_CONTENT_TYPE = "Content-Type";
		const string HTTP_HEADER_CONTENT_RANGE = "Content-Range";
		const string HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
		const string HTTP_HEADER_ENTITY_TAG = "ETag";
		const string HTTP_HEADER_LAST_MODIFIED = "Last-Modified";
		const string HTTP_HEADER_RANGE = "Range";
		const string HTTP_HEADER_IF_RANGE = "If-Range";
		const string HTTP_HEADER_IF_MATCH = "If-Match";
		const string HTTP_HEADER_IF_NONE_MATCH = "If-None-Match";
		const string HTTP_HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
		const string HTTP_HEADER_IF_UNMODIFIED_SINCE = "If-Unmodified-Since";
		const string HTTP_HEADER_UNLESS_MODIFIED_SINCE = "Unless-Modified-Since";

		const string HTTP_METHOD_GET = "GET";
		const string HTTP_METHOD_HEAD = "HEAD";

		private string fContentType = "application/octet-stream";

		public string ContentType
		{
			get { return fContentType; }
			set { fContentType = value; }
		}

		public void Dispose()
		{
		}

		public void ClearResponseData()
		{
			HttpResponse objResponse = HttpContext.Current.Response;
			objResponse.ClearContent();
			objResponse.ClearHeaders();
		}

		public DownloadState ProcessDownload(string fileName,string headerFileName)
		{

			HttpContext objContext = HttpContext.Current;
			// The Response object from the Context
			HttpResponse objResponse = objContext.Response;
			// The Request object from the Context
			HttpRequest objRequest = objContext.Request;

			// File information object...
			FileInformation objFile;

			// Long Arrays for Range values:
			// ...Begin() contains start positions for each requested Range
			long[] alRequestedRangesBegin = new long[1];
			// ...End() contains end positions for each requested Range
			long[] alRequestedRangesend = new long[1];

			// Response Header value: Content Length...
			int iResponseContentLength = 0;

			// The Stream we//re using to download the file in chunks...
			System.IO.Stream objStream;
			// Total Bytes to read (per requested range)
			int iBytesToRead;
			// Size of the Buffer for chunk-wise reading
			int iBufferSize = 25000;
			// The Buffer itself
			byte[] bBuffer = new byte[iBufferSize];
			// Amount of Bytes read
			int iLengthOfReadChunk = -1;

			// Indicates if the download was interrupted
			bool bDownloadBroken = false;

			// Indicates if this is a range request 
			bool bIsRangeRequest = false;
			// Indicates if this is a multipart range request
			bool bMultipart = false;

			// Loop counter used to iterate through the ranges
			int iLoop;

			if (string.IsNullOrEmpty(headerFileName))
				headerFileName = Path.GetFileName(fileName).Replace(' ', '-');

			// Content-Disposition value
			string Content_Disposition_File = "attachment; filename=" + headerFileName + "";

			// ToDo - your code here (Determine which file is requested)
			// Using objRequest, determine which file is requested to
			// be downloaded, and open objFile with that file:
			// Example:
			// objFile = New Download.FileInformation(<Full path to the requested file>)
			//objFile = new Download.FileInformation(objContext.Server.MapPath("~/download.zip"));
			objFile = new FileInformation(fileName);
			objFile.ContentType = this.ContentType;

			// Clear the current output content from the buffer
			objResponse.Clear();

			if (!(objRequest.HttpMethod.Equals(HTTP_METHOD_GET) ||
				objRequest.HttpMethod.Equals(HTTP_METHOD_HEAD)))
				// Currently, only the GET and HEAD methods 
				// are supported...
				objResponse.StatusCode = 501;  // Not implemented

			else if (!objFile.Exists)
				// The requested file could not be retrieved...
				objResponse.StatusCode = 404;  // Not found

			else if (objFile.Length > Int32.MaxValue)
				// The file size is too large... 
				objResponse.StatusCode = 413;  // Request Entity Too Large

			else if (!ParseRequestHeaderRange(objRequest, ref alRequestedRangesBegin, ref alRequestedRangesend,
				objFile.Length, ref bIsRangeRequest))
				// The Range request contained bad entries
				objResponse.StatusCode = 400;  // Bad Request

			else if (!CheckIfModifiedSince(objRequest, objFile))
				// The entity is still unmodified...
				objResponse.StatusCode = 304;  // Not Modified

			else if (!CheckIfUnmodifiedSince(objRequest, objFile))
				// The entity was modified since the requested date... 
				objResponse.StatusCode = 412;  // Precondition failed

			else if (!CheckIfMatch(objRequest, objFile))
				// The entity does not match the request... 
				objResponse.StatusCode = 412;  // Precondition failed

			else if (!CheckIfNoneMatch(objRequest, objResponse, objFile))
			{
				// The entity does match the none-match request, the response 
				// code was set inside the CheckifNoneMatch function
			}
			else
			{
				// Preliminary checks where successful... 

				if (bIsRangeRequest && CheckIfRange(objRequest, objFile))
				{
					// This is a Range request... 

					// if the Range arrays contain more than one entry,
					// it even is a multipart range request...
					bMultipart = (alRequestedRangesBegin.GetUpperBound(0) > 0);

					// Loop through each Range to calculate the entire Response length
					for (iLoop = alRequestedRangesBegin.GetLowerBound(0); iLoop <= alRequestedRangesBegin.GetUpperBound(0); iLoop++)
					{
						// The length of the content (for this range)
						iResponseContentLength += Convert.ToInt32(alRequestedRangesend[iLoop] - alRequestedRangesBegin[iLoop]) + 1;

						if (bMultipart)
						{
							//
							iResponseContentLength += HTTP_HEADER_Content_Disposition.Length;
							// if this is a multipart range request, calculate 
							// the length of the intermediate headers to send
							iResponseContentLength += MULTIPART_BOUNDARY.Length;
							iResponseContentLength += objFile.ContentType.Length;
							iResponseContentLength += alRequestedRangesBegin[iLoop].ToString().Length;
							iResponseContentLength += alRequestedRangesend[iLoop].ToString().Length;
							iResponseContentLength += objFile.Length.ToString().Length;
							// 49 is the length of line break and other 
							// needed characters in one multipart header
							iResponseContentLength += 49;
						}

					}

					if (bMultipart)
					{
						// if this is a multipart range request,  
						// we must also calculate the length of 
						// the last intermediate header we must send
						iResponseContentLength += MULTIPART_BOUNDARY.Length;
						// 8 is the length of dash and line break characters
						iResponseContentLength += 8;
					}
					else
					{
						// This is no multipart range request, so
						// we must indicate the response Range of 
						// in the initial HTTP Header 
						objResponse.AppendHeader(HTTP_HEADER_CONTENT_RANGE, "bytes " +
							alRequestedRangesBegin[0].ToString() + "-" +
							alRequestedRangesend[0].ToString() + "/" +
							objFile.Length.ToString());
					}

					// Range response 
					objResponse.StatusCode = 206; // Partial Response

				}
				else
				{
					// This is not a Range request, or the requested Range entity ID
					// does not match the current entity ID, so start a new download

					// Indicate the file//s complete size as content length
					iResponseContentLength = Convert.ToInt32(objFile.Length);

					// Return a normal OK status...
					objResponse.StatusCode = 200;
				}


				// Write file name into the Response
				objResponse.AppendHeader(HTTP_HEADER_Content_Disposition, Content_Disposition_File);

				// Write the content length into the Response
				objResponse.AppendHeader(HTTP_HEADER_CONTENT_LENGTH, iResponseContentLength.ToString());

				// Write the Last-Modified Date into the Response
				objResponse.AppendHeader(HTTP_HEADER_LAST_MODIFIED, objFile.LastWriteTimeUTC.ToString("r"));

				// Tell the client software that we accept Range request
				objResponse.AppendHeader(HTTP_HEADER_ACCEPT_RANGES, HTTP_HEADER_ACCEPT_RANGES_BYTES);

				// Write the file//s Entity Tag into the Response (in quotes!)
				objResponse.AppendHeader(HTTP_HEADER_ENTITY_TAG, "\"" + objFile.EntityTag + "\"");


				// Write the Content Type into the Response
				if (bMultipart)
					// Multipart messages have this special Type.
					// In this case, the file//s actual mime type is
					// written into the Response at a later time...
					objResponse.ContentType = MULTIPART_CONTENTTYPE;
				else
					// Single part messages have the files content type...
					objResponse.ContentType = objFile.ContentType;


				if (objRequest.HttpMethod.Equals(HTTP_METHOD_HEAD))
				{
					// Only the HEAD was requested, so we can quit the Response right here... 
				}
				else
				{

					// Flush the HEAD information to the client...
					objResponse.Flush();

					// Download is in progress...
					objFile.State = DownloadState.fsDownloadInProgress;

					// Open the file as filestream
					objStream = new FileStream(objFile.FullName, FileMode.Open,
						FileAccess.Read,
						FileShare.Read);
					try
					{

						//objStream = objFile.DataStream;

						// Now, for each requested range, stream the chunks to the client:
						for (iLoop = alRequestedRangesBegin.GetLowerBound(0); iLoop <= alRequestedRangesBegin.GetUpperBound(0); iLoop++)
						{

							// Move the stream to the desired start position...
							objStream.Seek(alRequestedRangesBegin[iLoop], SeekOrigin.Begin);

							// Calculate the total amount of bytes for this range
							iBytesToRead = Convert.ToInt32(alRequestedRangesend[iLoop] - alRequestedRangesBegin[iLoop]) + 1;

							if (bMultipart)
							{
								// if this is a multipart response, we must add 
								// certain headers before streaming the content:

								// The multipart boundary
								objResponse.Output.WriteLine("--" + MULTIPART_BOUNDARY);
								//objResponse.AppendHeader("--",MULTIPART_BOUNDARY);

								// The mime type of this part of the content 
								objResponse.Output.WriteLine(HTTP_HEADER_CONTENT_TYPE + ": " + objFile.ContentType);
								//objResponse.AppendHeader(HTTP_HEADER_CONTENT_TYPE,objFile.ContentType);

								// The actual range
								objResponse.Output.WriteLine(HTTP_HEADER_CONTENT_RANGE + ": bytes " +
									alRequestedRangesBegin[iLoop].ToString() + "-" +
									alRequestedRangesend[iLoop].ToString() + "/" +
									objFile.Length.ToString());

								/*objResponse.AppendHeader(HTTP_HEADER_CONTENT_RANGE,": bytes " +
									alRequestedRangesBegin[iLoop].ToString() + "-" +
									alRequestedRangesend[iLoop].ToString() + "/" +
									objFile.Length.ToString());
								*/
								// Indicating the end of the intermediate headers
								objResponse.Output.WriteLine();

							}

							// Now stream the range to the client...
							while (iBytesToRead > 0)
							{

								if (objResponse.IsClientConnected)
								{
									// Read a chunk of bytes from the stream
									iLengthOfReadChunk = objStream.Read(bBuffer, 0, Math.Min(bBuffer.Length, iBytesToRead));

									// Write the data to the current output stream.
									objResponse.OutputStream.Write(bBuffer, 0, iLengthOfReadChunk);

									// Flush the data to the HTML output.
									objResponse.Flush();

									// Clear the buffer
									bBuffer = new byte[iBufferSize];
									//ReDim bBuffer(iBufferSize);

									// Reduce BytesToRead
									iBytesToRead -= iLengthOfReadChunk;
								}
								else
								{
									// The client was or has disconneceted from the server... stop downstreaming...
									iBytesToRead = -1;
									bDownloadBroken = true;

								}
							}

							// In Multipart responses, mark the end of the part 
							if (bMultipart) objResponse.Output.WriteLine();

							// No need to proceed to the next part if the 
							// client was disconnected
							if (bDownloadBroken) break;
						}

						// At this point, the response was finished or cancelled... 

						if (bDownloadBroken)
							// Download is broken...
							objFile.State = DownloadState.fsDownloadBroken;

						else
						{
							if (bMultipart)
							{
								// In multipart responses, close the response once more with 
								// the boundary and line breaks
								objResponse.Output.WriteLine("--" + MULTIPART_BOUNDARY + "--");
								objResponse.Output.WriteLine();
							}

							// The download was finished
							objFile.State = DownloadState.fsDownloadFinished;
						}
					}
					finally
					{
						objStream.Close();
					}
				}
			}
			//objResponse.End();

			//====== return download state ======
			return objFile.State;
		}


		bool CheckIfRange(HttpRequest objRequest, FileInformation objFile)
		{
			string sRequestHeaderIfRange;

			// Checks the If-Range header if it was sent with the request.
			//
			// returns true if the header value matches the file//s entity tag,
			//              or if no header was sent,
			// returns false if a header was sent, but does not match the file.


			// Retrieve If-Range Header value from Request (objFile.EntityTag if none is indicated)
			sRequestHeaderIfRange = RetrieveHeader(objRequest, HTTP_HEADER_IF_RANGE, objFile.EntityTag);

			// If the requested file entity matches the current
			// file entity, return true
			return sRequestHeaderIfRange.Equals(objFile.EntityTag);
		}

		bool CheckIfMatch(HttpRequest objRequest, FileInformation objFile)
		{
			string sRequestHeaderIfMatch;
			string[] sEntityIDs;
			bool breturn = false;

			// Checks the If-Match header if it was sent with the request.
			//
			// returns true if one of the header values matches the file//s entity tag,
			//              or if no header was sent,
			// returns false if a header was sent, but does not match the file.


			// Retrieve If-Match Header value from Request (*, meaning any, if none is indicated)
			sRequestHeaderIfMatch = RetrieveHeader(objRequest, HTTP_HEADER_IF_MATCH, "*");

			if (sRequestHeaderIfMatch.Equals("*"))
				// The server may perform the request as if the
				// If-Match header does not exists...
				breturn = true;

			else
			{
				// One or more Match IDs where sent by the client software...
				sEntityIDs = sRequestHeaderIfMatch.Replace("bytes=", "").Split(",".ToCharArray());

				// Loop through all entity IDs, finding one 
				// which matches the current file's ID will
				// be enough to satisfy the If-Match
				for (int iLoop = sEntityIDs.GetLowerBound(0); iLoop <= sEntityIDs.GetUpperBound(0); iLoop++)
				{
					if (sEntityIDs[iLoop].Trim().Equals(objFile.EntityTag))
						breturn = true;
				}
			}
			// return the result...
			return breturn;
		}

		bool CheckIfNoneMatch(HttpRequest objRequest, HttpResponse objResponse, FileInformation objFile)
		{
			string sRequestHeaderIfNoneMatch;
			string[] sEntityIDs;
			bool breturn = true;
			string sreturn = "";
			// Checks the If-None-Match header if it was sent with the request.
			//
			// returns true if one of the header values matches the file//s entity tag,
			//              or if "*" was sent,
			// returns false if a header was sent, but does not match the file, or
			//               if no header was sent.

			// Retrieve If-None-Match Header value from Request (*, meaning any, if none is indicated)
			sRequestHeaderIfNoneMatch = RetrieveHeader(objRequest, HTTP_HEADER_IF_NONE_MATCH, String.Empty);

			if (sRequestHeaderIfNoneMatch.Equals(String.Empty))
				// Perform the request normally...
				breturn = true;
			else
			{
				if (sRequestHeaderIfNoneMatch.Equals("*"))
				{
					// The server must not perform the request 
					objResponse.StatusCode = 412;  // Precondition failed
					breturn = false;
				}
				else
				{
					// One or more Match IDs where sent by the client software...
					sEntityIDs = sRequestHeaderIfNoneMatch.Replace("bytes=", "").Split(",".ToCharArray());

					// Loop through all entity IDs, finding one which 
					// does not match the current file//s ID will be
					// enough to satisfy the If-None-Match
					for (int iLoop = sEntityIDs.GetLowerBound(0); iLoop <= sEntityIDs.GetUpperBound(0); iLoop++)
					{
						if (sEntityIDs[iLoop].Trim().Equals(objFile.EntityTag))
						{
							sreturn = sEntityIDs[iLoop];
							breturn = false;
						}
					}

					if (!breturn)
					{
						// One of the requested entities matches the current file//s tag,
						objResponse.AppendHeader("ETag", sreturn);
						objResponse.StatusCode = 304; // Not Modified
					}
				}
			}
			// return the result...
			return breturn;
		}

		bool CheckIfModifiedSince(HttpRequest objRequest, FileInformation objFile)
		{
			string sDate;
			DateTime dDate;
			bool breturn;

			// Checks the If-Modified header if it was sent with the request.
			//
			// returns true, if the file was modified since the 
			//               indicated date (RFC 1123 format), or
			//               if no header was sent,
			// returns false, if the file was not modified since
			//                the indicated date


			// Retrieve If-Modified-Since Header value from Request (Empty if none is indicated)
			sDate = RetrieveHeader(objRequest, HTTP_HEADER_IF_MODIFIED_SINCE, string.Empty);

			if (sDate.Equals(String.Empty))
				// No If-Modified-Since date was indicated, 
				// so just give this as true 
				breturn = true;

			else
			{
				try
				{
					// ... to parse the indicated sDate to a datetime value
					dDate = DateTime.Parse(sDate);
					// return true if the file was modified since or at the indicated date...
					breturn = (objFile.LastWriteTimeUTC >= DateTime.Parse(sDate));
				}
				catch
				{
					// Converting the indicated date value failed, return false 
					breturn = false;
				}
			}
			return breturn;
		}

		bool CheckIfUnmodifiedSince(HttpRequest objRequest, FileInformation objFile)
		{
			string sDate;
			DateTime dDate;
			bool breturn;


			// Checks the If-Unmodified or Unless-Modified-Since header, if 
			// one of them was sent with the request.
			//
			// returns true, if the file was not modified since the 
			//               indicated date (RFC 1123 format), or
			//               if no header was sent,
			// returns false, if the file was modified since the indicated date


			// Retrieve If-Unmodified-Since Header value from Request (Empty if none is indicated)
			sDate = RetrieveHeader(objRequest, HTTP_HEADER_IF_UNMODIFIED_SINCE, String.Empty);

			if (sDate.Equals(String.Empty))
				// If-Unmodified-Since was not sent, check Unless-Modified-Since... 
				sDate = RetrieveHeader(objRequest, HTTP_HEADER_UNLESS_MODIFIED_SINCE, String.Empty);


			if (sDate.Equals(String.Empty))
				// No date was indicated, 
				// so just give this as true 
				breturn = true;

			else
			{
				try
				{
					// ... to parse the indicated sDate to a datetime value
					dDate = DateTime.Parse(sDate);
					// return true if the file was not modified since the indicated date...
					breturn = objFile.LastWriteTimeUTC < DateTime.Parse(sDate);
				}
				catch
				{
					// Converting the indicated date value failed, return false 
					breturn = false;
				}
			}
			return breturn;
		}

		bool ParseRequestHeaderRange(HttpRequest objRequest, ref long[] lBegin, ref long[] lEnd , long lMax , ref bool bRangeRequest)
		{
			bool bValidRanges;
			string sSource;
			int iLoop;
			string[] sRanges;

			// Parses the Range header from the Request (if there is one)
			// returns true, if the Range header was valid, or if there was no 
			//               Range header at all (meaning that the whole 
			//               file was requested)
			// returns false, if the Range header asked for unsatisfieable 
			//                ranges

			// Retrieve Range Header value from Request (Empty if none is indicated)
			sSource = RetrieveHeader(objRequest, HTTP_HEADER_RANGE, String.Empty);

			if (sSource.Equals(String.Empty))
			{
				// No Range was requested, return the entire file range...

				lBegin = new long[1];
				//ReDim lBegin(0);
				lEnd = new long[1];
				//ReDim lEnd(0);

				lBegin[0] = 0;
				lEnd[0] = lMax - 1;

				// A valid range is returned
				bValidRanges = true;
				// no Range request
				bRangeRequest = false;
			}
			else
			{
				// A Range was requested... 

				// Preset value...
				bValidRanges = true;

				// return true for the bRange parameter, telling the caller
				// that the Request is indeed a Range request...
				bRangeRequest = true;

				// Remove "bytes=" from the beginning, and split the remaining 
				// string by comma characters
				sRanges = sSource.Replace("bytes=", "").Split(",".ToCharArray());
				lBegin = new long[sRanges.GetUpperBound(0) + 1];
				//ReDim lBegin(sRanges.GetUpperBound(0));
				lEnd = new long[sRanges.GetUpperBound(0) + 1];
				//ReDim lEnd(sRanges.GetUpperBound(0));

				// Check each found Range request for consistency
				for (iLoop = sRanges.GetLowerBound(0); iLoop <= sRanges.GetUpperBound(0); iLoop++)
				{

					// Split this range request by the dash character, 
					// sRange(0) contains the requested begin-value,
					// sRange(1) contains the requested end-value...
					string[] sRange = sRanges[iLoop].Split("-".ToCharArray());

					// Determine the end of the requested range
					if (sRange[1].Equals(String.Empty))
						// No end was specified, take the entire range
						lEnd[iLoop] = lMax - 1;
					else
						// An end was specified...
						lEnd[iLoop] = long.Parse(sRange[1]);

					// Determine the begin of the requested range
					if (sRange[0].Equals(String.Empty))
					{
						// No begin was specified, which means that
						// the end value indicated to return the last n
						// bytes of the file:

						// Calculate the begin
						lBegin[iLoop] = lMax - 1 - lEnd[iLoop];
						// ... to the end of the file...
						lEnd[iLoop] = lMax - 1;
					}
					else
						// A normal begin value was indicated...
						lBegin[iLoop] = long.Parse(sRange[0]);


					// Check if the requested range values are valid, 
					// return false if they are not.
					//
					// Note:
					// Do not clean invalid values up by fitting them into
					// valid parameters using Math.Min and Math.Max, because
					// some download clients (like Go!Zilla) might send invalid 
					// (e.g. too large) range requests to determine the file limits!

					// Begin and end must not exceed the file size
					if ((lBegin[iLoop] > (lMax - 1)) || (lEnd[iLoop] > (lMax - 1)))
						bValidRanges = false;

					// Begin and end cannot be < 0
					if ((lBegin[iLoop] < 0) || (lEnd[iLoop] < 0))
						bValidRanges = false;

					// End must be larger or equal to begin value
					if (lEnd[iLoop] < lBegin[iLoop])
						// The requested Range is invalid...
						bValidRanges = false;

				}

			}
			return bValidRanges;
		}

		string RetrieveHeader(HttpRequest objRequest, string sHeader,string sDefault)
		{
			string sreturn;

			// Retrieves the indicated Header//s value from the Request,
			// if the header was not sent, sDefault is returned.
			//
			// If the value contains quote characters, they are removed.

			sreturn = objRequest.Headers[sHeader];

			if ((sreturn == null) || (sreturn.Equals(string.Empty)))
				// The Header wos not found in the Request, 
				// return the indicated default value...
				return sDefault;

			else
				// return the found header value, stripped of any quote characters...
				return sreturn.Replace("\"", "");

		}


		string GenerateHash(System.IO.Stream objStream, long lBegin ,long lEnd)
		{
			byte[] bByte = new byte[Convert.ToInt32(lEnd)];

			objStream.Read(bByte, Convert.ToInt32(lBegin), Convert.ToInt32(lEnd - lBegin) + 1);

			//Instantiate an MD5 Provider object
			MD5CryptoServiceProvider Md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();

			//Compute the hash value from the source
			byte[] ByteHash = Md5.ComputeHash(bByte);

			//And convert it to String format for return
			return Convert.ToBase64String(ByteHash);
		}

	}

	public class FileInformation
	{
		DownloadState m_nState;
		DateTime fCreatTime;
		string fFileName = "";
		string m_ContentType = "application/octet-stream";
		long? fileLength = null;

		public FileInformation(string fileName)
		{
			fFileName = fileName;
			fCreatTime = DateTime.Now;
		}

		public bool Exists
		{
			get
			{
				return File.Exists(fFileName);
			}
		}

		public string FullName
		{
			get { return fFileName;/*m_objFile.FullName;*/}
		}

		public DateTime LastWriteTimeUTC
		{
			get { return fCreatTime.ToUniversalTime(); }
		}
		public long Length
		{
			get
			{
				if (fileLength.HasValue == false)
				{
					FileInfo info = new FileInfo(fFileName);
					fileLength = info.Length;
				}
				return fileLength.Value;

			}
		}

		public string ContentType
		{
			get
			{
				return m_ContentType;
			}
			set
			{
				m_ContentType = value;
			}
		}
		public string EntityTag
		{
			get
			{
				return fFileName.GetHashCode().ToString();//"MyExampleFileID";
			}
		}
		public virtual DownloadState State
		{
			get
			{
				return m_nState;
			}
			set
			{
				m_nState = value;
			}
		}
	}


	public enum DownloadState
	{
		/// Clear: No download in progress, 
		/// the file can be manipulated
		fsClear = 1,

		/// Locked: A dynamically created file must
		/// not be changed
		fsLocked = 2,

		/// In Progress: File is locked, and download 
		/// is currently in progress
		fsDownloadInProgress = 6,

		/// Broken: File is locked, download was in
		/// progress, but was cancelled 
		fsDownloadBroken = 10,

		/// Finished: File is locked, download
		/// was completed
		fsDownloadFinished = 18
	};
}

 

فایل های ضمیمه

ایمان مدائنی

نویسنده 1299 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید