FileHandler文件处理,实行文件从临时目录保存到正式目录、生成图片对象的缩略图、获取文件信息等功能。
实例:实现用户头像图片的保存,并生成对象的缩略图。
1、 创建filehandler.xml文件
在Config目录下创建filehandler.xml文件
<FileHandler>
<DirectoryMappings>
<Directory Name="Temp" Path="E:\File\TempDirectory\" WritePath="" Url="/file/temp/"></Directory>
<Directory Name="Images" Path="E:\File\RealDirectory\" WritePath="" Url="/file/Images/">
<Channel Name="Product" Path="E:\File\RealDirectory\ProductModel\" WritePath="" Url=""></Channel>
<Channel Name="UserHead" Path="E:\File\RealDirectory\UserHead\" WritePath="" Url=""></Channel>
</Directory>
<Directory Name="Xml">
<Channel Name="Platform_xml" Path="" WritePath="" Url=""></Channel>
</Directory>
</DirectoryMappings>
</FileHandler>
2、 创建FileHandler.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
namespace MyStudy.Utility
{
/// <summary>
/// 缩略图类型枚举
/// </summary>
public enum AbbrType
{
None,
Default,
Product, //商品
UserHead //用户头像
}
/// <summary>
/// 类略图后缀名
/// </summary>
public enum AbbrName
{
_none,
_abbr,
_pdz,
_pdl,
_uhs, //用户头像小图
_uhm, //用户头像中图
_uhb, //用户头像大图
}
/// <summary>
/// 文件目录类型枚举(对应FileHandler DirectoryMappings)
/// </summary>
public enum FileHandlerDirectoryType
{
Xml,
Images,
Temp
}
/// <summary>
/// 文件目录信息类(对应FileHandler DirectoryMappings 的节点属性)
/// </summary>
public class FileHandlerDirectoryInfo
{
public string Name { set; get; }
public string Path { set; get; }
public string WritePath { set; get; }
public string Url { set; get; }
}
/// <summary>
/// 文件处理类
/// </summary>
public class FileHandler
{
private static XmlDocument fileHandlerXmlDoc = null; //FileHandler.xml文件节点
static FileHandler()
{
if (fileHandlerXmlDoc == null || fileHandlerXmlDoc.InnerText == "")
{
fileHandlerXmlDoc = new XmlDocument();
fileHandlerXmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"\Config\FileHandler.xml");
}
}
/// <summary>
/// 将临时文件转移到正式目录,并返回文件名
/// </summary>
/// <param name="fileName">文件名</param>
/// <param name="directoryType">类型</param>
/// <param name="channel">子频道</param>
/// <param name="haveAbbr">缩略图</param>
/// <returns>文件名,如201204/01/xxxx.gif</returns>
public string SaveAsFormalFile(string fileName, FileHandlerDirectoryType directoryType, string channel, AbbrType abbrType)
{
if ((fileName == "") || (fileName == null))
{
throw new Exception("文件名不能为空!");
}
fileName = fileName.Replace("_.", ".");
string dateDirectory = GetDateDirectory();
try
{
//获取临时文件
FileInfo tempFileInfo = new FileInfo(this.GetDirectoryInfo(FileHandlerDirectoryType.Temp, null).WritePath + fileName);
//正式文件
FileInfo formalFileInfo = new FileInfo(this.GetDirectoryInfo(directoryType, channel).WritePath + dateDirectory + fileName);
//判断临时文件是否存在
if (tempFileInfo.Exists)
{
//判断正式目录是否存在,不存在则创建
try
{
if (!Directory.Exists(formalFileInfo.DirectoryName))
{
Directory.CreateDirectory(formalFileInfo.DirectoryName);
}
}
catch (Exception ex)
{
throw new Exception("执行Exists或CreateDirectory失败," + ex.Message);
}
//判断是否在正式目录存在同名文件,存在则删除
if (formalFileInfo.Exists)
{
try
{
formalFileInfo.Delete();
}
catch (Exception ex)
{
throw new Exception("执行Delete失败," + ex.Message);
}
}
//把文件从临时目录移动到正式目录
try
{
tempFileInfo.MoveTo(formalFileInfo.FullName);
}
catch (Exception ex)
{
throw new Exception("执行MoveTo失败," + ex.Message);
}
}
else
{
formalFileInfo = new FileInfo(this.GetDirectoryInfo(directoryType, channel).WritePath + fileName);
}
//图片类型 生成缩略图
if (directoryType == FileHandlerDirectoryType.Images && abbrType != AbbrType.None)
{
FileInfo fileThumb = new FileInfo(formalFileInfo.FullName);
if (fileThumb.Exists)
{
Image imageStream = Image.FromFile(fileThumb.FullName);
string fileThumbName = fileThumb.Name.Substring(0, fileThumb.Name.LastIndexOf(fileThumb.Extension));
switch (abbrType)
{
case AbbrType.Default: //缩略图文件处理
SaveThumbImage(imageStream, this.GetDirectoryInfo(FileHandlerDirectoryType.Images, channel).WritePath + dateDirectory + fileThumbName + AbbrName._abbr.ToString() + fileThumb.Extension, fileThumb.Extension, 88, 65, 1);
break;
case AbbrType.Product: //商品缩图文件处理
SaveThumbImage(imageStream, this.GetDirectoryInfo(FileHandlerDirectoryType.Images, channel).WritePath + dateDirectory + fileThumbName + AbbrName._pdz.ToString() + fileThumb.Extension, fileThumb.Extension, 120, 120, 3);
SaveThumbImage(imageStream, this.GetDirectoryInfo(FileHandlerDirectoryType.Images, channel).WritePath + dateDirectory + fileThumbName + AbbrName._pdl.ToString() + fileThumb.Extension, fileThumb.Extension, 180, 135, 1);
break;
case AbbrType.UserHead: //用户头像缩图文件处理
SaveThumbImage(imageStream, this.GetDirectoryInfo(FileHandlerDirectoryType.Images, channel).WritePath + dateDirectory + fileThumbName + AbbrName._uhs.ToString() + fileThumb.Extension, fileThumb.Extension, 30, 30, 3);
SaveThumbImage(imageStream, this.GetDirectoryInfo(FileHandlerDirectoryType.Images, channel).WritePath + dateDirectory + fileThumbName + AbbrName._uhm.ToString() + fileThumb.Extension, fileThumb.Extension, 50, 50, 3);
SaveThumbImage(imageStream, this.GetDirectoryInfo(FileHandlerDirectoryType.Images, channel).WritePath + dateDirectory + fileThumbName + AbbrName._uhb.ToString() + fileThumb.Extension, fileThumb.Extension, 100, 100, 3);
break;
}
imageStream.Dispose();
}
}
}
catch (Exception ex)
{
throw new Exception("文件从临时目录移动到正式目录时出错:" + ex.Message);
}
return (dateDirectory + fileName).Replace(@"\", "/");
}
/// <summary>
/// 获取目录的读写路径信息
/// </summary>
/// <param name="projectType"></param>
/// <param name="directoryType"></param>
/// <param name="channel"></param>
/// <returns></returns>
public string GetThumbnailImgSrc(FileHandlerDirectoryType directoryType, string channel, AbbrName abbrType, string imgName)
{
string result = "";
XmlNode node = null;
if (string.IsNullOrEmpty(imgName)) return "";
if (!string.IsNullOrEmpty(channel))
{
node = fileHandlerXmlDoc.SelectSingleNode("/FileHandler/DirectoryMappings/Directory[@Name='" + directoryType.ToString() + "']");
if (node == null)
{
throw new Exception("FileHandler无法找到配置节点!");
}
node = node.SelectSingleNode("Channel[@Name='" + channel + "']");
}
else
{
node = fileHandlerXmlDoc.SelectSingleNode("/FileHandler/DirectoryMappings/Directory[@Name='" + directoryType.ToString() + "']");
}
if (node == null)
{
throw new Exception("FileHandler无法找到配置节点!");
}
string fileName = imgName.Split('.')[0];
string extension = imgName.Split('.')[1];
string fileFormat = "{0}{1}{2}.{3}";
string[] urls = node.Attributes["Url"].Value.Trim().Split(',');
Random random = new Random();
string url = urls[random.Next(urls.Length)];
if (abbrType == AbbrName._none)//原图
{
result = string.Format(fileFormat, url, fileName, "", extension);
}
else result = string.Format(fileFormat, url, fileName, abbrType, extension);
return result;
}
/// <summary>
/// 把图片流保存成缩略图
/// </summary>
/// <param name="imgPhoto">图片文件的Image数据流</param>
/// <param name="fileName">保存目标文件的物理地址</param>
/// <param name="fileExt">保存目标文件扩展名,含有.</param>
/// <param name="maxWidth">最大宽</param>
/// <param name="maxHeight">最大高</param>
/// <param name="thumbType">缩略方式:1(等比例缩小),2(自动计算从中间截取),3(使用空白填充法保证大小),4(硬性压缩到指定的大小宽高度),5(如果图片超宽或超高,则只缩小超出的部份,其他部份不变)</param>
public void SaveThumbImage(Image imgPhoto, string fileName, string fileExt, int maxWidth, int maxHeight, int thumbType)
{
//判断缩略图是否存在
FileInfo filInfo = new FileInfo(fileName);
if (filInfo.Exists)
{
try
{
filInfo.Delete();
}
catch
{
return;
}
}
#region 变量实始化
int nx = 0;
int ny = 0;
int nw = maxWidth;
int nh = maxHeight;
int ox = 0;
int oy = 0;
int ow = imgPhoto.Width;
int oh = imgPhoto.Height;
double owh = (double)ow / (double)oh;
double mwh = (double)maxWidth / (double)maxHeight;
Image bitmap = null;
Graphics g = null;
bool isRate = false;
#endregion
try
{
#region 尺寸 选择生成模式
switch (thumbType)
{
case 1:
if (maxHeight == 1 || owh > mwh)
{
maxHeight = maxWidth * oh / ow;
nh = maxHeight;
}
else
{
maxWidth = maxHeight * ow / oh;
nw = maxWidth;
}
break;
case 2:
if (owh > mwh)
{
int w = oh * maxWidth / maxHeight;
ox = (ow - w) / 2;
ow = w;
}
else
{
int h = ow * maxHeight / maxWidth;
oy = (oh - h) / 2;
oh = h;
}
break;
case 3:
if (owh > mwh)
{
nh = maxWidth * oh / ow;
ny = (maxHeight - nh) / 2;
}
else
{
nw = maxHeight * ow / oh;
nx = (maxWidth - nw) / 2;
}
break;
case 5:
isRate = false;
if (maxHeight >= oh)
{
maxHeight = oh;
nh = maxHeight;
}
else isRate = true;
if (maxWidth >= ow)
{
maxWidth = ow;
nw = maxWidth;
}
else isRate = true;
if (isRate)
{
if (ow - maxWidth > oh - maxHeight)
{
nh = Convert.ToInt32(decimal.Parse(oh.ToString()) * (decimal.Parse(maxWidth.ToString()) / decimal.Parse(ow.ToString())));
if (nh <= 0) nh = 1;
maxHeight = nh;
nw = maxWidth;
}
else if (ow - maxWidth < oh - maxHeight)
{
nw = Convert.ToInt32(decimal.Parse(ow.ToString()) * (decimal.Parse(maxHeight.ToString()) / decimal.Parse(oh.ToString())));
if (nw <= 0) nw = 1;
maxWidth = nw;
nh = maxHeight;
}
}
break;
case 6:
isRate = false;
nh = oh;
if (maxWidth >= ow)
{
maxWidth = ow;
nw = maxWidth;
}
else isRate = true;
if (isRate)
{
decimal locRate = (decimal.Parse(maxWidth.ToString()) / decimal.Parse(ow.ToString()));
nw = Convert.ToInt32(decimal.Parse(ow.ToString()) * locRate);
if (nw <= 0) nw = 1;
maxWidth = nw;
nh = Convert.ToInt32(decimal.Parse(oh.ToString()) * locRate);
if (nh <= 0) nh = 1;
if (maxHeight > nh)
{
ny = (maxHeight - nh) / 2;
}
else maxHeight = nh;
}
else maxHeight = oh;
break;
}
#endregion
#region 生成缩略图并且保存
bitmap = new Bitmap(maxWidth, maxHeight);//新建一个bmp图片
g = Graphics.FromImage(bitmap);//新建一个画板
g.InterpolationMode = InterpolationMode.HighQualityBicubic;//设置高质量插值法
g.SmoothingMode = SmoothingMode.None;//.HighQuality;//设置高质量,低速度呈现平滑程度
g.Clear(Color.White);//清空画布并以白背景色填充
g.DrawImage(
imgPhoto,
new Rectangle(nx, ny, nw, nh),
new Rectangle(ox, oy, ow, oh),
GraphicsUnit.Pixel); //在指定位置并且按指定大小绘制原图片的指定部分
long[] quality = new long[1];
quality[0] = 100;
System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
encoderParams.Param[0] = encoderParam;
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();//获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象。
ImageCodecInfo imageCodecInfo = null;
ImageFormat imageFormat = GetImageFormat(fileExt);
for (int i = 0; i < arrayICI.Length; i++)
{
if (arrayICI[i].FormatDescription.Equals(imageFormat.ToString().ToUpper()))
{
imageCodecInfo = arrayICI[i];
break;
}
}
if (imageCodecInfo != null)
{
bitmap.Save(fileName, imageCodecInfo, encoderParams);
}
else
{
bitmap.Save(fileName, imageFormat);//保存
}
#endregion
}
catch (System.Exception exp)
{
}
finally
{
if (g != null) g.Dispose();
if (bitmap != null) bitmap.Dispose();//释放
}
}
/// <summary>
/// 获取目录的读写路径信息
/// </summary>
/// <param name="projectType"></param>
/// <param name="directoryType"></param>
/// <param name="channel"></param>
/// <returns></returns>
public FileHandlerDirectoryInfo GetDirectoryInfo(FileHandlerDirectoryType directoryType, string channel)
{
FileHandlerDirectoryInfo result = new FileHandlerDirectoryInfo();
XmlNode node = null;
if (!string.IsNullOrEmpty(channel))
{
node = fileHandlerXmlDoc.SelectSingleNode("/FileHandler/DirectoryMappings/Directory[@Name='" + directoryType.ToString() + "']");
if (node == null)
{
throw new Exception("FileHandler无法找到配置节点!");
}
node = node.SelectSingleNode("Channel[@Name='" + channel + "']");
}
else
{
node = fileHandlerXmlDoc.SelectSingleNode("/FileHandler/DirectoryMappings/Directory[@Name='" + directoryType.ToString() + "']");
}
if (node == null)
{
throw new Exception("FileHandler无法找到配置节点!");
}
result.Name = node.Attributes["Name"].Value.Trim();
result.Path = node.Attributes["Path"].Value.Trim();
result.WritePath = string.IsNullOrEmpty(node.Attributes["WritePath"].Value.Trim()) ? result.Path : node.Attributes["WritePath"].Value.Trim();
string[] urls = node.Attributes["Url"].Value.Trim().Split(',');
Random random = new Random();
string url = urls[random.Next(urls.Length)];
result.Url = url;
return result;
}
/// <summary>
/// 获取图片类型
/// </summary>
/// <param name="ext"></param>
/// <returns></returns>
private ImageFormat GetImageFormat(string ext)
{
switch (ext.ToLower())
{
case ".jpg":
case ".jpeg":
return ImageFormat.Jpeg;
case ".gif":
return ImageFormat.Gif;
case ".bmp":
return ImageFormat.Bmp;
case ".png":
return ImageFormat.Png;
default:
return ImageFormat.Jpeg;
}
}
private string GetDateDirectory()
{
return DateTime.Now.ToString(@"yyyyMM") + @"\" + DateTime.Now.ToString("dd") + @"\";
}
}
}
3、 使用
/// <summary>
/// 保存图片(保存头像)
/// </summary>
public static void SavePicTest()
{
FileHandler fileHandler = new FileHandler();
string picName = "2013128135359435142.jpg";
picName = fileHandler.SaveAsFormalFile(picName, FileHandlerDirectoryType.Images, "UserHead", AbbrType.UserHead);
Console.WriteLine("图片保存成功,图片名称:" + picName);
}
/// <summary>
/// 获取图片(获取头像)
/// </summary>
public static void GetPicTest()
{
FileHandler fileHandler = new FileHandler();
string picName = "201302/15/2013128135359435142.jpg";
string picHead1 = fileHandler.GetThumbnailImgSrc(FileHandlerDirectoryType.Images, "UserHead", AbbrName._uhs, picName); //获取小图
string picHead2 = fileHandler.GetThumbnailImgSrc(FileHandlerDirectoryType.Images, "UserHead", AbbrName._uhm, picName); //获取中图
string picHead3 = fileHandler.GetThumbnailImgSrc(FileHandlerDirectoryType.Images, "UserHead", AbbrName._uhm, picName); //获取大图
Console.WriteLine("小图头像:" + picHead1);
Console.WriteLine("中图头像:" + picHead2);
Console.WriteLine("大图头像:" + picHead3);
}