·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 图片分布式存储
优点:图片分布式存储主要解决服务器存储压力,以及提高查询速度;
方案:用户发起上传请求,在发起请求的服务器中,根据图片信息表中的数据查找可用的服务器,此时可能查找多台服务器,那么根据从状态表筛选出可用的图片服务器集合记作C,并获取集合的总记录数N。然后用随机函数产生一个随机数R1并用R1与N进行取余运算记作I=R1%N。则C[I]即为要保存图片的图片服务器,选择可用的服务器,然后使用WebClient发起请求,在可用的服务器中存储图片,具体如下:
解决步骤:
1.在数据库中新建两个表分别是ImageServerInfo,ImageInfo;
表:ImageServerInfo
CREATE TABLE [dbo].[ImageServerInfo]([ServerId] [int] IDENTITY(1,1) NOT NULL,[ServerName] [nvarchar](32) NOT NULL,[ServerUrl] [nvarchar](100) NOT NULL,[FlgUsable] [bit] NOT NULL, CONSTRAINT [PK_ImageServerInfo] PRIMARY KEY CLUSTERED ([ServerId] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
表:ImageInfo
CREATE TABLE [dbo].[ImageInfo]([Id] [int] IDENTITY(1,1) NOT NULL,[ImageName] [nvarchar](100) NOT NULL,[ImageServerId] [int] NOT NULL, CONSTRAINT [PK_ImageInfo] PRIMARY KEY CLUSTERED ([Id] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
ALTER TABLE [dbo].[ImageInfo] WITH CHECK ADD CONSTRAINT [FK_ImageInfo_ImageServerInfo] FOREIGN KEY([ImageServerId])REFERENCES [dbo].[ImageServerInfo] ([ServerId])GO
ALTER TABLE [dbo].[ImageInfo] CHECK CONSTRAINT [FK_ImageInfo_ImageServerInfo]GO
2.新建mvc项目 添加一个控制器 并添加以下方法
public ActionResult FileUpload() { HttpPostedFileBase file = Request.Files["ImgFile"];
string fileName = file.FileName;
string fileExt = Path.GetExtension(fileName);
if (fileExt == ".jpg" || fileExt == ".png") { ImageServerEntities dbContext = new ImageServerEntities();
var isiList = dbContext.ImageServerInfo.Where(x => x.FlgUsable == true).ToList();
int countN = isiList.Count();
//从状态表筛选出可用的图片服务器集合记作C,并获取集合的总记录数N。然后用随机函数产生一个随机数R1并用R1与N进行取余运算记作I=R1%N。则C[I]即为要保存图片的图片服务器 Random rand = new Random();
int r1 = rand.Next();
int i = r1 % countN;
ImageServerInfo isi = isiList[i];
string url = string.Format("http://{0}/FileUp.ashx?serverId={1}&ext={2}", isi.ServerUrl, isi.ServerId, fileExt);
WebClient wc = new WebClient();
wc.UploadData(url, StreamToByteArray(file.InputStream));
return Content("success"); } else { return Content("请注意文件类型!"); } }
private byte[] StreamToByteArray(Stream stream) { byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Seek(0, SeekOrigin.Begin);//设置当前流所在的位置:第一个参数是相对于第二个参数指定的位置的相对偏移位置。
return buffer; }
3.新建两个web应用程序 分别代表分布在不同服务器上的应用程序 并在一般处理程序下添加如下方法
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain";
string imgExt = context.Request["ext"];//获取文件扩展名
string serverId = context.Request["serverId"];//获取数据库中表ImageServerInfo的标识
string imgNewName = Guid.NewGuid().ToString();//用Guid为新的文件重命名
string path = "/ImgFileUpload/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day + "/";//按照每年每月每天创建新的文件夹 避免因为大量的图片文件在同一个文件夹中,造成打开文件卡死现象
Directory.CreateDirectory(Path.GetDirectoryName(context.Server.MapPath(path)));//创建文件夹 此时类Directory内部已经判断是否存在该文件无需再次判断
string imgFullPath = path + imgNewName + imgExt;//拼接文件路径
using (FileStream fs=File.OpenWrite(context.Request.MapPath(imgFullPath))) { context.Request.InputStream.CopyTo(fs);//将请求文件流拷贝到需要写入文件的文件流
ImageServerEntities dbContext = new ImageServerEntities(); ImageInfo img = new ImageInfo() { ImageName = imgFullPath, ImageServerId=Convert.ToInt32(serverId) }; dbContext.ImageInfo.Add(img); dbContext.SaveChanges(); } }
4.分别启动相应的应用程序 上传文件并测试