zoukankan      html  css  js  c++  java
  • FastDfs

    FastDfs是一个开源的轻量级分布式文件系统,其原理可以查看http://blog.chinaunix.net/uid-20196318-id-4058561.html,然后部署安装部分可参考http://blog.csdn.net/poechant/article/details/7209313,这里只是简单的说明下在C#中如何使用FastDfs。

    首先是通过Nuget下载dll,具体地址为https://www.nuget.org/packages/FastDFS/

    然后可以通过程序来设置相关Tracker服务器地址及群组信息,也可以通过配置文件来配置

    通过代码方式的话是如下方式

    new FastDfsConfig
    {
    //FastDfsServer =...,
    //GroupName =...
    };
    而通过配置文件方式的话,需要在配置文件的configSections节点中添加如下配置
    <section name="fastdfs" type="FastDFS.Client.Config.FastDfsConfigurationSectionHandler, FastDFS.Client" />
    其中fastdfs为默认节点名,当然name也可以指定为其它值,然后实际配置如下
    <fastdfs>
    <FastDfsConfig GroupName="group1">
    <FastDfsServer IpAddress="192.168.1.103" Port="22122" />
    <!--<FastDfsServer IpAddress="192.168.1.104" Port="22122" />-->
    </FastDfsConfig>
    </fastdfs>
    然后在代码中通过下列代码来初始化
    Config = FastDfsManager.GetConfigSection();
    ConnectionManager.InitializeForConfigSection(Config);
    FastDfs相关的操作代码主要集中在FastDFSClient类中,然后实际项目中我们只是用到了UploadFile,所以也就只是简单地做了个封装
    using FastDFS.Client;
    using FastDFS.Client.Config;
    using System.IO;

    public static class FastDfsHelper
    {
    /// <summary>
    /// Dfs文件
    /// </summary>
    public class FastDfsFile
    {
    /// <summary>
    /// Dfs群组名
    /// </summary>
    public string GroupName { get; private set; }
    /// <summary>
    /// Dfs文件路径(包含文件名)
    /// </summary>
    public string FileName { get; private set; }
    public FastDfsFile(string groupName, string fileName)
    {
    if (string.IsNullOrWhiteSpace(groupName))
    {
    throw new ArgumentNullException("groupName can not be null.");
    }
    if (string.IsNullOrWhiteSpace(fileName))
    {
    throw new ArgumentNullException("fileName can not be null.");
    }
    this.GroupName = groupName;
    this.FileName = fileName;
    }
    /// <summary>
    /// 获取文件在服务器上访问的路径(不包含域名部分)
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
    return string.Format("{0}/{1}", this.GroupName, this.FileName);
    }
    }
    static readonly FastDfsConfig Config;
    static FastDfsHelper()
    {
    Config = FastDfsManager.GetConfigSection();
    ConnectionManager.InitializeForConfigSection(Config);
    }
    /// <summary>
    /// 上传文件
    /// </summary>
    /// <param name="contentByte">文件数组</param>
    /// <param name="fileExt"></param>
    /// <returns></returns>
    public static FastDfsFile Upload(byte[] contentByte, string fileExt)
    {
    var node = FastDFSClient.GetStorageNode(Config.GroupName);
    return new FastDfsFile(Config.GroupName, FastDFSClient.UploadFile(node, contentByte, fileExt.Trim('.')));
    }
    /// <summary>
    /// 上传文件
    /// </summary>
    /// <param name="stream">文件流</param>
    /// <param name="fileExt"></param>
    /// <returns></returns>
    public static FastDfsFile Upload(Stream stream, string fileExt)
    {
    using (stream)
    {
    byte[] contentByte = new byte[stream.Length];
    stream.Read(contentByte, 0, contentByte.Length);
    return Upload(contentByte, fileExt);
    }
    }
    /// <summary>
    /// 将数据流读取成byte数组,并在读取完成后将流当前位置设置为0
    /// </summary>
    /// <param name="stream"></param>
    /// <returns></returns>
    public static byte[] StreamToBytes(Stream stream)
    {
    byte[] bytes = new byte[stream.Length];
    stream.Read(bytes, 0, bytes.Length);
    // 设置当前流的位置为流的开始
    stream.Seek(0, SeekOrigin.Begin);
    return bytes;
    }
    /// <summary>
    /// 移除文件
    /// </summary>
    /// <param name="groupName"></param>
    /// <param name="fileName"></param>
    public static void Remove(string groupName, string fileName)
    {
    FastDFSClient.RemoveFile(groupName, fileName);
    }
    }
    然后因为我们主要是上传图片,所以这里还从网上找了段压缩的代码,然后简单的调整了下
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.IO;

    public static class ImageHelper
    {
    /// <summary>
    /// JPG编码解码器信息,为null表示未安装
    /// </summary>
    public static readonly ImageCodecInfo JPEGICIinfo;
    static ImageHelper()
    {
    JPEGICIinfo = GetJPEGICIinfo();
    }
    /// <summary>
    /// 图片压缩并获得压缩后的数据流,如果出现异常则返回null,注意使用完之后释放
    /// </summary>
    /// <param name="imgByte">原始图片内容</param>
    /// <param name="dHeight">压缩后的最大高度</param>
    /// <param name="dWidth">压缩后的最大宽度</param>
    /// <param name="flag">压缩质量 1-100</param>
    /// <returns></returns>
    public static Stream GetPicThumbnail(byte[] imgByte, int dHeight, int dWidth, int flag)
    {
    using (var sStream = new MemoryStream(imgByte))
    {
    Image iSource = Image.FromStream(sStream);
    ImageFormat tFormat = iSource.RawFormat;
    //按比例缩放
    var zSize = GetZoomSize(new Size(iSource.Width, iSource.Height), dWidth, dHeight);
    Bitmap ob = new Bitmap(zSize.Width, zSize.Height);
    using (Graphics g = Graphics.FromImage(ob))
    {
    g.CompositingQuality = CompositingQuality.HighQuality;
    g.SmoothingMode = SmoothingMode.HighQuality;
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.DrawImage(iSource, new Rectangle(0, 0, zSize.Width, zSize.Height), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);
    }
    MemoryStream rStream = new MemoryStream();
    try
    {
    if (JPEGICIinfo != null)
    {
    ob.Save(rStream, JPEGICIinfo, GetEncoderParameters(flag));
    }
    else
    {
    ob.Save(rStream, tFormat);
    }
    rStream.Position = 0;
    }
    catch
    {
    rStream.Dispose();
    rStream = null;
    }
    finally
    {
    iSource.Dispose();
    ob.Dispose();
    }
    return rStream;
    }
    }
    private static Size GetZoomSize(Size sSize, int dWidth, int dHeight)
    {
    int sW = sSize.Width, sH = sSize.Height;
    //按比例缩放
    if (sSize.Width > dHeight || sSize.Width > dWidth) //将**改成c#中的或者操作符号
    {
    if ((sSize.Width * dHeight) > (sSize.Height * dWidth))
    {
    sW = dWidth;
    sH = (dWidth * sSize.Height) / sSize.Width;
    }
    else
    {
    sH = dHeight;
    sW = (sSize.Width * dHeight) / sSize.Height;
    }
    }
    return new Size(sW, sH);
    }
    private static ImageCodecInfo GetJPEGICIinfo()
    {
    ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
    ImageCodecInfo jpegICIinfo = null;
    for (int x = 0; x < arrayICI.Length; x++)
    {
    if (arrayICI[x].FormatDescription.Equals("JPEG"))
    {
    jpegICIinfo = arrayICI[x];
    break;
    }
    }
    return jpegICIinfo;
    }
    private static EncoderParameters GetEncoderParameters(int flag)
    {
    //以下代码为保存图片时,设置压缩质量
    EncoderParameters ep = new EncoderParameters();
    long[] qy = new long[1];
    qy[0] = flag;//设置压缩的比例1-100
    EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
    ep.Param[0] = eParam;
    return ep;
    }
    }
    简单的使用代码如下
    string localPath = @"E:demoPic3.jpg";
    string newPath1 = @"E:demoPicNN03.jpg";
    var imgByte = File.ReadAllBytes(localPath);
    //图片压缩
    var stream = ImageHelper.GetPicThumbnail(imgByte, 500, 500, 70);
    if (stream != null)
    {
    using (stream)
    {
    byte[] bytes = FastDfsHelper.StreamToBytes(stream);
    //文件上传
    var file = FastDfsHelper.Upload(stream, Path.GetExtension(localPath).Trim('.'));
    Console.WriteLine(file);//file.ToString()结果就为排除fastDfs访问域名后完整的图片访问路径
    File.WriteAllBytes(newPath1, bytes);//本地存储以便与上传到Dfs的文件进行比较
    }
    }
    ---------------------
    作者:娃都会打酱油了
    来源:CSDN
    原文:https://blog.csdn.net/starfd/article/details/54575199
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    系统剪切板的使用UIPasteboard
    iOS开发之GCD总结
    OC报错,after command failed: Directory not empty
    一个女孩被车多次撞到的经历
    iOS一个很好的内存检测工具
    iOS 数据库sqlite3.0操作--超简单--看我就够啦
    推送碰到的一个坑
    iOS之3DTouch的使用---很简单,看我就够啦~~
    简谈造成循环引用的原因以及处理办法
    关于拼过消息推送回调,然后跳转到指定界面
  • 原文地址:https://www.cnblogs.com/zengpeng/p/11153133.html
Copyright © 2011-2022 走看看