using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace System.Utility.File
{
    public class FileHelper
    {
        /// <summary>  
        /// 获取文件的MD5码  
        /// </summary>  
        /// <param name="fileName">传入的文件名（含路径及后缀名）</param>  
        /// <returns></returns>  
        public static string GetMD5HashFromFile(string fileName)
        {
            try
            {
                FileStream file = new FileStream(fileName, System.IO.FileMode.Open);
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] retVal = md5.ComputeHash(file);
                file.Close();
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
                return sb.ToString();
            }
            catch (Exception ex)
            {
                throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
            }
        }

        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string GetThumbImg(string path, string fileName, string fileExt)
        {
            string[] filetypes = new string[] { ".jpg", ".jpeg", ".gif", ".bmp", ".png" };

            if (filetypes.Contains(fileExt))
            {
                FileStream file = new FileStream(path + fileName, System.IO.FileMode.Open);
                //获取图片的高度和宽度
                System.Drawing.Image Img = System.Drawing.Image.FromStream(file);
                int _Width = Img.Width;
                int _Height = Img.Height;

                int _sHeight = 120;//设置生成缩略图的高度 
                int _sWidth = 120;//设置生成缩略图的宽度

                #region 缩略图大小只设置了最大范围，并不是实际大小
                float realbili = (float)_Width / (float)_Height;
                float wishbili = (float)_sWidth / (float)_sHeight;

                //实际图比缩略图最大尺寸更宽矮，以宽为准
                if (realbili > wishbili)
                {
                    _sHeight = (int)((float)_sWidth / realbili);
                }
                //实际图比缩略图最大尺寸更高长，以高为准
                else
                {
                    _sWidth = (int)((float)_sHeight * realbili);
                }
                #endregion

                string[] filenames = fileName.Split('.');
                string OutThumbFileName = filenames[0].ToString() + "_s." + filenames[1].ToString();
                string ImgFilePath = path + OutThumbFileName;

                System.Drawing.Image newImg = Img.GetThumbnailImage(_sWidth, _sHeight, null, System.IntPtr.Zero);
                newImg.Save(ImgFilePath);
                newImg.Dispose();

                Img.Dispose();

                return OutThumbFileName;
            }
            else
            {
                return "";
            }

        }



        //判断文件夹是否存在
        public static bool FolderExits(string path)
        {
            DirectoryInfo dir = new DirectoryInfo(path);
            if (dir.Exists)//文件夹存在
            {
                return true;
            }
            else
            {
                //dir.Create();//不存在就创建一个
                return false;
            }
        }
        //创建一个文件夹，存在就创建失败
        public static bool CreateNewFolder(string path)
        {
            DirectoryInfo dir = new DirectoryInfo(path);

            if (!dir.Exists)
            {
                dir.Create();
                return true;
            }
            else
                return false;
        }
        /// <summary>
        /// 在指定目录下创建指定名称文件夹
        /// </summary>
        /// <param name="ParentsPath"></param>
        /// <param name="NewFolderName"></param>
        /// <returns></returns>
        public static bool CreateNewFolder(string ParentsPath, string NewFolderName)
        {
            string CreatePath = ParentsPath + @"\" + NewFolderName;
            DirectoryInfo dir = new DirectoryInfo(CreatePath);

            if (!dir.Exists)
            {
                dir.Create();
                return true;
            }
            else
                return false;
        }
        /// <summary>
        /// 返回目录下的所有文件名
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static ArrayList getAllFiles(string path)
        {
            DirectoryInfo dir = new DirectoryInfo(path);
            if (dir.Exists)
            {
                FileInfo[] fileinfo = dir.GetFiles();
                ArrayList list = new ArrayList();
                foreach (FileInfo f in fileinfo)
                {
                    list.Add(f.Name);
                }
                return list;
            }
            else
                return null;
        }
        /// <summary>
        /// 计算文件夹的大小
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        public static long DirSize(DirectoryInfo d)
        {
            long Size = 0;
            // Add file sizes.
            FileInfo[] fis = d.GetFiles();//获得目录文件列表
            foreach (FileInfo fi in fis)
            {
                Size += fi.Length;
            }
            // Add subdirectory sizes.
            DirectoryInfo[] dis = d.GetDirectories();//获取目录子目录列表
            foreach (DirectoryInfo di in dis)
            {
                Size += DirSize(di);
            }
            return Size;
        }
        /// <summary>
        /// 把文件夹得大小转换成比较合适的表示单位
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        public static string ViewSize(long size)
        {
            long m = size;
            string viewstr;

            if ((m / 1024) > 0)//表示可以转换成KB
            {
                m = m / 1024;//转换成KB

                if ((m / 1024) > 0)//表示可以转换成MB
                {
                    m = m / 1024;//转换成MB了

                    if ((m / 1024) > 0)//表示可以转换成GB
                    {
                        m = m / 1024;//转换成GB了
                        viewstr = m.ToString() + "GB";
                    }
                    else
                    {
                        viewstr = m.ToString() + "MB";
                    }
                }
                else
                {
                    viewstr = m.ToString() + "KB";
                }
            }
            else
            {
                viewstr = m.ToString() + "byte";
            }
            return viewstr;
        }
        /// <summary>
        /// 删除指定目录和内容
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        public static bool delDir(string dir)
        {
            bool flag = false;
            DirectoryInfo d = new DirectoryInfo(dir);
            if (d.Exists)//判断目录是否存在
            {
                try
                {
                    d.Delete();
                    flag = true;
                }
                catch (Exception e) { flag = false; }
            }
            return flag;
        }
        /// <summary>
        /// 删除指定文件
        /// </summary>
        /// <param name="fil"></param>
        /// <returns></returns>
        public static bool delFile(string fil)
        {
            bool flag = false;
            FileInfo d = new FileInfo(fil);
            if (d.Exists)//判断目录是否存在
            {
                try
                {
                    d.Delete();
                    flag = true;
                }
                catch (Exception e) { flag = false; }
            }
            return flag;
        }
        /// <summary>
        /// 判断文件是否存在
        /// </summary>
        /// <param name="fil"></param>
        /// <returns></returns>
        public static bool FileExists(string fil)
        {
            bool flag = false;
            FileInfo d = new FileInfo(fil);
            return d.Exists;
        }
        public static void Copy(string sourceDirectory, string targetDirectory)
        {
            DirectoryInfo diSource = new DirectoryInfo(sourceDirectory);
            DirectoryInfo diTarget = new DirectoryInfo(targetDirectory);

            CopyAll(diSource, diTarget);
        }
        /// <summary>
        /// 复制目录及子文件到指定目录
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
        {
            // Check if the target directory exists, if not, create it.
            //if (FolderExits(target.FullName) == false)
            //{
            //    Directory.CreateDirectory(target.FullName);
            //}
            CreateNewFolder(target.FullName);

            // Copy each file into it's new directory.
            foreach (FileInfo fi in source.GetFiles())
            {
                Console.WriteLine(@"Copying {0}\{1}", target.FullName, fi.Name);
                fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
            }

            // Copy each subdirectory using recursion.
            foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
            {
                DirectoryInfo nextTargetSubDir =
                    target.CreateSubdirectory(diSourceSubDir.Name);
                CopyAll(diSourceSubDir, nextTargetSubDir);
            }
        }



        /// <summary>
        /// 循环读取某个目录下的所有文件和目录，查询有关每一项的一些信息。返回一个文件列表
        /// </summary>
        /// <param name="strCurrentDir"></param>
        public static List<fileEntity> FileView(string strCurrentDir)
        {
            List<fileEntity> fileList = new List<fileEntity>();
            DirectoryInfo dir = new DirectoryInfo(strCurrentDir);

            foreach (FileSystemInfo fsi in dir.GetFileSystemInfos())//这个循环再读取文件的信息
            {
                try
                {
                    //FileSystemInfo 对象可以表示文件或目录，从而可以作为 FileInfo 或 DirectoryInfo 对象的基础。 当分析许多文件和目录时，请使用该基类。
                    FileInfo fi;
                    DirectoryInfo di;
                    //创建一个自己写的实体类的实体
                    fileEntity newfile = new fileEntity();
                    if (fsi is FileInfo)//外层循环读取文件信息
                    {
                        //表示当前fsi是文件
                        fi = (FileInfo)fsi;
                        newfile.fileName = fi.Name;
                        newfile.fileExt = fi.Extension;
                        newfile.fileSize = fi.Length;
                        newfile.FileModify = fi.LastWriteTime;
                        //通过扩展名来选择文件显示图标
                        switch (newfile.fileExt)
                        {
                            case ".gif":
                                newfile.picName = "gif.gif";
                                break;
                            default:
                                newfile.picName = "other.gif";
                                break;
                        }
                        newfile.picName = "<img src='" + newfile.picName + "' width=25 height=20>";
                    }
                    else
                    {
                        di = (DirectoryInfo)fsi;
                        newfile.fileName = di.Name;
                        newfile.fileSize = DirSize(di);//调用计算文件夹大小的方法
                        newfile.FileModify = di.LastWriteTime;
                        newfile.picName = "<img src='directory.gif' width=25 height=20>";
                    }
                    fileList.Add(newfile);
                }
                catch (Exception e) { }
            }
            return fileList;

        }


        /// <summary>
        /// 显示目录和文件
        /// </summary>
        /// <param name="path"></param>
        public static void All(string path)
        {
            FileInfo fi;//文件
            DirectoryInfo di;//目录
            DirectoryInfo dir = null;
            int i = 0; //控制行的颜色
            try
            {
                dir = new DirectoryInfo(path);
            }
            catch (Exception e) { }
            foreach (FileSystemInfo fsi in dir.GetFileSystemInfos())
            {
                try
                {
                    fileEntity newfile = new fileEntity();
                    FolderEntity folder = new FolderEntity();
                    newfile.fileName = "";
                    newfile.picName = "";
                    newfile.fileExt = "";
                    newfile.fileSize = 0;
                    folder.folderName = "";
                    folder.picName = "";

                    i += 1;
                    if (fsi is FileInfo)//判断当前读取的是不是一个文件
                    {
                        //表示当前fsi是文件
                        fi = (FileInfo)fsi;
                        newfile.fileName = fi.Name;
                        newfile.fileExt = fi.Extension;
                        newfile.fileSize = fi.Length;
                        newfile.FileModify = fi.LastWriteTime;

                        //将文件加上可以下载文件的链接


                        newfile.fileName = "<a href='........'></a>";


                        //通过扩展名来选择文件显示图标

                        //Response.Write(Session["DataBasePath"].ToString()+"\\filetype\\"+pfun.getFileExt(FileExt)+".gif");

                        if (fsi.Exists)
                        {
                            switch (newfile.fileExt)
                            {
                                case ".gif":
                                    newfile.picName = "gif.gif";
                                    break;
                                default:
                                    newfile.picName = "other.gif";
                                    break;
                            }
                        }
                        else
                        {
                            newfile.picName = "unknown.gif";
                        }


                        /*
                        switch(FileExt)
                        {
                            case ".gif":
                                FilePic = "gif.gif";
                                break;
                            default:
                                FilePic = "other.gif";
                                break;
                        }
                        */

                        newfile.picName = "<img src='filetype/" + newfile.picName + "' width=16 height=16>";

                    }
                    else
                    {
                        //当前为目录
                        di = (DirectoryInfo)fsi;
                        folder.folderName = di.Name;

                        //给目录加上链接

                        folder.folderName = "<a href='.......'><a>";
                        folder.lastTime = di.LastWriteTime;
                        folder.picName = "<img src='filetype/folder.gif' width=16 height=16>";

                    }
                }
                catch (Exception e) { }
            }


        }


    }
    public class fileEntity
    {
        public string fileName { get; set; }
        public string fileExt { get; set; }
        public long fileSize { get; set; }
        public DateTime FileModify { get; set; }
        public string picName { get; set; }

    }
    public class FolderEntity
    {

        public string folderName { get; set; }
        public DateTime lastTime { get; set; }
        public string picName { get; set; }
    }
}
