·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 图片分布式存储

图片分布式存储

作者:佚名      ASP.NET网站开发编辑:admin      更新时间:2022-07-23

图片分布式存储

优点:图片分布式存储主要解决服务器存储压力,以及提高查询速度;

方案:用户发起上传请求,在发起请求的服务器中,根据图片信息表中的数据查找可用的服务器,此时可能查找多台服务器,那么根据从状态表筛选出可用的图片服务器集合记作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.分别启动相应的应用程序 上传文件并测试