public void Create(StorageFileInfo file, Stream content)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            var storage = this.Storage;

            if (storage == null)
            {
                throw new InvalidOperationException("The Storage is null.");
            }

            //如果文件路径为空则为它设置一个有效的文件路径
            if (string.IsNullOrWhiteSpace(file.Path))
            {
                file.Path = this.GetFilePath(file);
            }

            storage.SetValue(GetFileKey(file.FileId), file.ToDictionary());

            var collection = storage.GetValue(GetFileCollectionKey(file.BucketId)) as ICollection <string>;

            if (collection != null)
            {
                collection.Add(file.FileId.ToString("n"));
            }
            else
            {
                storage.SetValue(GetFileCollectionKey(file.BucketId), new string[] { file.FileId.ToString("n") });
            }

            if (content != null)
            {
                var path = Zongsoft.IO.Path.Parse(file.Path);

                //确认文件的所在目录是存在的,如果不存在则创建相应的目录
                FileSystem.Directory.Create(path.Schema + ":" + path.DirectoryName);

                //创建或打开指定路径的文件流
                using (var stream = FileSystem.File.Open(file.Path, FileMode.Create, FileAccess.Write))
                {
                    //将文件内容写入到创建或打开的文件流中
                    content.CopyTo(stream);
                }
            }
        }
        private string GetFilePath(StorageFileInfo fileInfo)
        {
            var timestamp  = fileInfo.CreatedTime;
            var parameters = Zongsoft.Collections.DictionaryExtension.ToDictionary <string, string>(Environment.GetEnvironmentVariables());

            parameters.Add("date", timestamp.ToString("yyyyMMdd"));
            parameters.Add("time", timestamp.ToString("HHmmss"));
            parameters.Add("year", timestamp.Year.ToString("0000"));
            parameters.Add("month", timestamp.Month.ToString("00"));
            parameters.Add("day", timestamp.Day.ToString("00"));

            var resolvedPath = this.ResolveTextWithParameters(this.GetBucketPath(fileInfo.BucketId), parameters);

            //返回当前文件的完整虚拟路径
            return(Zongsoft.IO.Path.Combine(resolvedPath, string.Format("[{0}]{1:n}{2}", fileInfo.BucketId, fileInfo.FileId, System.IO.Path.GetExtension(fileInfo.Name).ToLowerInvariant())));
        }
		public static StorageFileInfo FromDictionary(IDictionary dictionary)
		{
			if(dictionary == null || dictionary.Count < 1)
				return null;

			object bucketId, fileId, name, type, size, path, totalVisits, createdTime, modifiedTime, visitedTime;

			if(!dictionary.TryGetValue("BucketId", out bucketId))
				return null;

			if(!dictionary.TryGetValue("FileId", out fileId))
				return null;

			dictionary.TryGetValue("Name", out name);
			dictionary.TryGetValue("Type", out type);
			dictionary.TryGetValue("Size", out size);
			dictionary.TryGetValue("Path", out path);
			dictionary.TryGetValue("TotalVisits", out totalVisits);
			dictionary.TryGetValue("CreatedTime", out createdTime);
			dictionary.TryGetValue("ModifiedTime", out modifiedTime);
			dictionary.TryGetValue("VisitedTime", out visitedTime);

			var result = new StorageFileInfo(Zongsoft.Common.Convert.ConvertValue<int>(bucketId), Zongsoft.Common.Convert.ConvertValue<Guid>(fileId))
			{
				Name = Zongsoft.Common.Convert.ConvertValue<string>(name),
				Type = Zongsoft.Common.Convert.ConvertValue<string>(type),
				Size = Zongsoft.Common.Convert.ConvertValue<long>(size),
				Path = Zongsoft.Common.Convert.ConvertValue<string>(path),
				TotalVisits = Zongsoft.Common.Convert.ConvertValue<int>(totalVisits),
				CreatedTime = Zongsoft.Common.Convert.ConvertValue<DateTime>(createdTime),
				ModifiedTime = Zongsoft.Common.Convert.ConvertValue<DateTime?>(modifiedTime),
				VisitedTime = Zongsoft.Common.Convert.ConvertValue<DateTime?>(visitedTime),
			};

			foreach(var key in dictionary.Keys)
			{
				if(key == null)
					continue;

				if(key.ToString().StartsWith(EXTENDEDPROPERTIESPREFIX))
					result.ExtendedProperties[key.ToString().Substring(EXTENDEDPROPERTIESPREFIX.Length)] = dictionary[key];
			}

			return result;
		}
        public StorageFileInfo GetInfo(Guid fileId)
        {
            var storage = this.Storage;

            if (storage == null)
            {
                throw new InvalidOperationException("The Storage is null.");
            }

            var dictionary = storage.GetValue(GetFileKey(fileId)) as IDictionary;

            if (dictionary != null)
            {
                return(StorageFileInfo.FromDictionary(dictionary));
            }

            return(null);
        }
        public Guid?Copy(Guid fileId, int bucketId)
        {
            var storage = this.Storage;

            if (storage == null)
            {
                throw new InvalidOperationException("The Storage is null.");
            }

            var info = this.GetInfo(fileId);

            if (info == null)
            {
                return(null);
            }

            if (info.BucketId == bucketId)
            {
                return(fileId);
            }

            var newInfo = new StorageFileInfo(bucketId, Guid.NewGuid())
            {
                Name = info.Name,
                Type = info.Type,
                Size = info.Size,
                Path = info.Path,
            };

            if (info.HasExtendedProperties)
            {
                foreach (var entry in info.ExtendedProperties)
                {
                    newInfo.ExtendedProperties.Add(entry.Key, entry.Value);
                }
            }

            this.Create(newInfo, null);

            return(newInfo.FileId);
        }
        public Stream Open(Guid fileId, out StorageFileInfo info)
        {
            var storage = this.Storage;

            if (storage == null)
            {
                throw new InvalidOperationException("The Storage is null.");
            }

            info = null;

            var dictionary = storage.GetValue(GetFileKey(fileId)) as IDictionary;

            if (dictionary == null || dictionary.Count < 1)
            {
                return(null);
            }

            info = StorageFileInfo.FromDictionary(dictionary);

            if (dictionary is Zongsoft.Common.IAccumulator)
            {
                ((Zongsoft.Common.IAccumulator)dictionary).Increment("TotalVisits");
            }
            else
            {
                long totalVisits = 0;
                dictionary.TryGetValue <long>("TotalVisits", out totalVisits);
                dictionary["TotalVisits"] = totalVisits + 1;
            }

            dictionary["VisitedTime"] = DateTime.Now;

            if (string.IsNullOrWhiteSpace(info.Path))
            {
                return(null);
            }

            return(FileSystem.File.Open(info.Path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read));
        }
		public void Create(StorageFileInfo file, Stream content)
		{
			if(file == null)
				throw new ArgumentNullException("file");

			var storage = this.Storage;

			if(storage == null)
				throw new InvalidOperationException("The Storage is null.");

			//如果文件路径为空则为它设置一个有效的文件路径
			if(string.IsNullOrWhiteSpace(file.Path))
				file.Path = this.GetFilePath(file);

			storage.SetValue(GetFileKey(file.FileId), file.ToDictionary());

			var collection = storage.GetValue(GetFileCollectionKey(file.BucketId)) as ICollection<string>;

			if(collection != null)
				collection.Add(file.FileId.ToString("n"));
			else
				storage.SetValue(GetFileCollectionKey(file.BucketId), new string[] { file.FileId.ToString("n") });

			if(content != null)
			{
				var path = Zongsoft.IO.Path.Parse(file.Path);

				//确认文件的所在目录是存在的,如果不存在则创建相应的目录
				FileSystem.Directory.Create(path.Schema + ":" + path.DirectoryName);

				//创建或打开指定路径的文件流
				using(var stream = FileSystem.File.Open(file.Path, FileMode.Create, FileAccess.Write))
				{
					//将文件内容写入到创建或打开的文件流中
					content.CopyTo(stream);
				}
			}
		}
		private string GetFilePath(StorageFileInfo fileInfo)
		{
			var timestamp = fileInfo.CreatedTime;
			var parameters = Zongsoft.Collections.DictionaryExtension.ToDictionary<string, string>(Environment.GetEnvironmentVariables());

			parameters.Add("date", timestamp.ToString("yyyyMMdd"));
			parameters.Add("time", timestamp.ToString("HHmmss"));
			parameters.Add("year", timestamp.Year.ToString("0000"));
			parameters.Add("month", timestamp.Month.ToString("00"));
			parameters.Add("day", timestamp.Day.ToString("00"));

			var resolvedPath = this.ResolveTextWithParameters(this.GetBucketPath(fileInfo.BucketId), parameters);

			//返回当前文件的完整虚拟路径
			return Zongsoft.IO.Path.Combine(resolvedPath, string.Format("[{0}]{1:n}{2}", fileInfo.BucketId, fileInfo.FileId, System.IO.Path.GetExtension(fileInfo.Name).ToLowerInvariant()));
		}
		public Guid? Copy(Guid fileId, int bucketId)
		{
			var storage = this.Storage;

			if(storage == null)
				throw new InvalidOperationException("The Storage is null.");

			var info = this.GetInfo(fileId);

			if(info == null)
				return null;

			if(info.BucketId == bucketId)
				return fileId;

			var newInfo = new StorageFileInfo(bucketId, Guid.NewGuid())
			{
				Name = info.Name,
				Type = info.Type,
				Size = info.Size,
				Path = info.Path,
			};

			if(info.HasExtendedProperties)
			{
				foreach(var entry in info.ExtendedProperties)
				{
					newInfo.ExtendedProperties.Add(entry.Key, entry.Value);
				}
			}

			this.Create(newInfo, null);

			return newInfo.FileId;
		}
		public Stream Open(Guid fileId, out StorageFileInfo info)
		{
			var storage = this.Storage;

			if(storage == null)
				throw new InvalidOperationException("The Storage is null.");

			info = null;

			var dictionary = storage.GetValue(GetFileKey(fileId)) as IDictionary;

			if(dictionary == null || dictionary.Count < 1)
				return null;

			info = StorageFileInfo.FromDictionary(dictionary);

			if(dictionary is Zongsoft.Common.IAccumulator)
				((Zongsoft.Common.IAccumulator)dictionary).Increment("TotalVisits");
			else
			{
				long totalVisits = 0;
				dictionary.TryGetValue<long>("TotalVisits", out totalVisits);
				dictionary["TotalVisits"] = totalVisits + 1;
			}

			dictionary["VisitedTime"] = DateTime.Now;

			if(string.IsNullOrWhiteSpace(info.Path))
				return null;

			return FileSystem.File.Open(info.Path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
		}
			private string GetFilePath(StorageFileInfo fileInfo)
			{
				//返回当前文件的完整虚拟路径
				return Zongsoft.IO.Path.Combine(_bucketPath, string.Format("[{0}]{1:n}{2}", fileInfo.BucketId, fileInfo.FileId, System.IO.Path.GetExtension(fileInfo.Name).ToLowerInvariant()));
			}
			public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
			{
				if(parent == null)
					throw new ArgumentNullException("parent");

				if(headers == null)
					throw new ArgumentNullException("headers");

				if(string.IsNullOrEmpty(headers.ContentDisposition.FileName))
				{
					_isFormData.Add(true);
					return new MemoryStream();
				}

				var contentType = headers.ContentType == null ? string.Empty : headers.ContentType.MediaType;

				if(string.IsNullOrWhiteSpace(contentType))
					contentType = System.Web.MimeMapping.GetMimeMapping(headers.ContentDisposition.FileName);

				_isFormData.Add(false);

				//创建一个文件信息实体对象
				var fileInfo = new StorageFileInfo(_bucketId)
				{
					Name = Zongsoft.Common.StringExtension.RemoveCharacters(headers.ContentDisposition.FileName, System.IO.Path.GetInvalidFileNameChars()).Trim('"', '\''),
					Type = contentType,
					Size = headers.ContentDisposition.Size.HasValue ? headers.ContentDisposition.Size.Value : -1,
				};

				fileInfo.Path = this.GetFilePath(fileInfo);

				try
				{
					//将文件信息对象加入到集合中
					_fileData.Add(fileInfo);

					if(!FileSystem.Directory.Exists(_bucketPath))
						FileSystem.Directory.Create(_bucketPath);

					return FileSystem.File.Open(fileInfo.Path, FileMode.CreateNew, FileAccess.Write);
				}
				catch
				{
					_fileData.Remove(fileInfo);
					throw;
				}
			}