文件服务设计

远古时期,在谷歌还是41的时候我们用ftp当文件服务器,存文件等。随着谷歌高版本对ftp的不支持(不支持img直接加载ftp路径)。外加安保说ftp地址带用户密码不安全,以及ftp对服务器和客户端都有端口范围段的要求。为此拉开了文件服务的转型。

开始给的建议是用sftp,发现sftp对img加载url不行,不能保持和ftp的兼容。然后就想啊想怎么解决文件服务问题。

基于我对Base64串的理解,最终设计了http的文件服务。那么http文件服务是怎么样的呢?

首先我们知道给网站目录下放图片文件,让img元素加载http的url是没毛病的。也符合新浏览器抛弃ftp的初衷,让img加载http路径。

那么就可以确定基于http对img加载和ftp是没差别的。对于下载图片怎么解决?对于下载文件可以判断路径头是ftp还是http地址包装统一api,来统一文件服务操作。

解决了img加载和文件下载问题后剩下的就是文件怎么上传到http指定目录这个关键问题了。这里就要借助webservice结合base64串实现文件服务的上传功能了。首先上传客户端把要上传的文件转换为Base64串,然后调用文件服务的Webservice上传。文件服务的Webservice把Base64串还原成文件后存入指定路径,如此就可以包装得到http文件服务。然后对文件服务上传下载整合统一api就得到一个支持ftp和http的文件服务。且比ftp原生更简单。这也是检验文件服务为什么要web环境的原因。

抽取ftp和http文件服务操作api共性就看抽取力了。

		/// <summary>
        /// 上传文件到文件服务
        /// </summary>
        /// <param name="serverPath">服务地址,如果是FTP就是FTP带密码的地址,如果是SFTP就是SFTP地址,如果是网站就是检验service/asmx/wbsDHCLISUpFileServiceHandler.asmx地址</param>
        /// <param name="fileFullName">文件带路径的全名</param>
        /// <param name="fileNewName">文件上传到服务器的新名称</param>
        /// <param name="remotePath">相对路径</param>
        /// <returns>空成功,非空返回失败原因</returns>
        public string Upload(string serverPath, string fileFullName, string fileNewName, string remotePath = "")
		
		/// <summary>
        /// 上传文件到文件服务
        /// </summary>
        /// <param name="serverPath">服务地址,如果是FTP就是FTP带密码的地址,如果是SFTP就是SFTP地址,如果是网站就是检验service/asmx/wbsDHCLISUpFileServiceHandler.asmx地址</param>
        /// <param name="fileFullName">文件带路径的全名</param>
        /// <param name="fileNewName">文件上传到服务器的新名称</param>
        /// <param name="remotePath">相对路径</param>
        /// <returns>空成功,非空返回失败原因</returns>
        public string SyncFile(string serverPath, string fileFullName, string fileNewName, string remotePath = "")
		
		/// <summary>
        /// 上传文件到文件服务
        /// </summary>
        /// <param name="serverPath">服务地址,如果是FTP就是FTP带密码的地址,如果是SFTP就是SFTP地址,如果是网站就是检验service/asmx/wbsDHCLISUpFileServiceHandler.asmx地址</param>
        /// <param name="stream">文件流</param>
        /// <param name="fileNewName">文件上传到服务器的新名称</param>
        /// <param name="remotePath">相对路径</param>
        /// <returns>空成功,非空返回失败原因</returns>
        public string Upload(string serverPath, System.IO.Stream stream, string fileNewName, string remotePath = "")
		
		/// <summary>
        /// 从服务下载文件
        /// </summary>
        /// <param name="fileServerFullPath">文件在服务的全路径</param>
        /// <param name="fileFullName">文件本地保存的全路径</param>
        public void Download(string fileServerFullPath, string fileFullName, bool passive = false)
		
		/// <summary>
        /// 从服务下载文件
        /// </summary>
        /// <param name="fileServerFullPath">文件在服务的全路径</param>
        public System.IO.Stream DownloadStream(string fileServerFullPath, bool passive = false)
		
		/// <summary>
        /// 修改文件名
        /// </summary>
        /// <param name="serverPath">服务地址,如果是FTP就是FTP带密码的地址,如果是SFTP就是SFTP地址,如果是网站就是检验service/asmx/wbsDHCLISUpFileServiceHandler.asmx地址</param>
        /// <param name="currentFilename">当前文件名</param>
        /// <param name="newFilename">修改的文件名</param>
        /// <param name="remotePath">相对路径</param>
        public void ReName(string serverPath, string currentFilename, string newFilename, string remotePath = "")
		
		/// <summary>
        /// 移动文件
        /// </summary>
        /// <param name="currentFullFilename">原路径</param>
        /// <param name="newFullFilename">新路径</param>
        public void Move(string currentFullFilename, string newFullFilename)
		
		/// <summary>
        /// 删除服务器上的文件
        /// </summary>
        /// <param name="fileServerFullPath">文件在服务的全路径</param>
        public void Delete(string fileServerFullPath)

使用起来就简单了

//创建文件操作对象
LIS.File.Core.FileService fileService = new LIS.File.Core.FileService();
File.Core.FileServiceFlags.Err = "";
//下载文件
fileService.Download(url, fileFullName, passive);
if (File.Core.FileServiceFlags.Err != "")
{
    return "-1^" + File.Core.FileServiceFlags.Err;
}
			
//上传文件		
string ret = fileService.Upload(ftps[0].ParaValue, fileFullName, fileName, reAddr);

一生二,二生三,三生万物,这样就可以包装对外文件服务了
比如把外部ftp或http文件拉人检验文件服务。或者把Base64串上传到文件服务,或者把一个ftp或http地址的文件得到Base64串。给外部提供的文件附加服务就基于此。

        /// <summary>
        /// 把Ftp文件或者http文件上传到检验文件服务器
        /// </summary>
        /// <param name="url">外部路径</param>
        /// <param name="fileName">文件名</param>
        /// <param name="reAddr">相对目录名称可以为空</param>
        /// <param name="passive">ftp模式</param>
        /// <returns>成功返回全的保存路径,失败返回-1^原因</returns>
        public string FtpOrHttpFileUpToLisInner(string url, string fileName, string reAddr, bool passive = false)
        {
            if (reAddr == null)
            {
                reAddr = "";
            }
            if (reAddr == "")
            {
                reAddr = "/LISOutReportFile/";
            }
            if (fileName == "")
            {
                return "-1^文件名必须传入!";
            }
            if (url == "")
            {
                return "-1^url必须传入!";
            }
            //判断C盘trak是否存在
            string tmpPath = @"C:\TRAK\TmpReportFile";
            if (!Directory.Exists("C:\\TRAK"))
            {
                //新建文件夹
                Directory.CreateDirectory("C:\\TRAK");
            }
            if (!Directory.Exists(tmpPath))
            {
                //新建文件夹   
                Directory.CreateDirectory(tmpPath);
            }
            //删除两天前文件
            DeleteOldFile(tmpPath, 2);
            //文件保存全路径
            string fileFullName = tmpPath + "\\" + fileName;
            if (System.IO.File.Exists(fileFullName))
            {
                System.IO.File.Delete(fileFullName);
            }
            LIS.File.Core.FileService fileService = new LIS.File.Core.FileService();
            File.Core.FileServiceFlags.Err = "";
            fileService.Download(url, fileFullName, passive);
            if (File.Core.FileServiceFlags.Err != "")
            {
                return "-1^" + File.Core.FileServiceFlags.Err;
            }
            Hashtable hs = new Hashtable();
            hs.Add("Code", "LABReportImageFTP");
            hs.Add("ParaType", "HOS");
            //获得ftp配置参数
            List<SYSParameter> ftps = EntityManager.FindAll<SYSParameter>(hs);
            if (ftps[0].ParaValue.Length > 0 && ftps[0].ParaValue[ftps[0].ParaValue.Length - 1] == '/')
            {
                reAddr = reAddr.Substring(1);
            }
            string fullPath = ftps[0].ParaValue + reAddr + fileName;
            string ret = fileService.Upload(ftps[0].ParaValue, fileFullName, fileName, reAddr);
            System.IO.File.Delete(fileFullName);
            if (ret != "")
            {
                return "-1^" + ret;
            }
            return fullPath;
        }

        /// <summary>
        /// 把Base64串转换成文件上传到检验文件服务器
        /// </summary>
        /// <param name="base64Str">base64串</param>
        /// <param name="fileName">文件名</param>
        /// <param name="reAddr">相对目录名称可以为空</param>
        /// <param name="passive">ftp模式</param>
        /// <returns>成功返回全的保存路径,失败返回-1^原因</returns>
        [WebMethod]
        public string Base64FileUpToLis(string base64Str, string fileName,string reAddr, bool passive = false)
        {
            bool verify = InterfaceWhiteList.Verify("LIS.BLL.WebService.LISFileService.Base64FileUpToLis", "把Base64串转换成文件上传到检验文件服务器");
            if (reAddr==null)
            {
                reAddr = "";
            }
            if (reAddr=="")
            {
                reAddr = "/LISOutReportFile/";
            }
            if(fileName=="")
            {
                return "-1^文件名必须传入!";
            }
            if (base64Str == "")
            {
                return "-1^Base64串必须传入!";
            }
            //判断C盘trak是否存在
            string tmpPath = @"C:\TRAK\TmpReportFile";
            if (!Directory.Exists("C:\\TRAK"))
            {
                //新建文件夹
                Directory.CreateDirectory("C:\\TRAK");
            }
            if (!Directory.Exists(tmpPath))
            {
                //新建文件夹   
                Directory.CreateDirectory(tmpPath);
            }
            //删除两天前文件
            DeleteOldFile(tmpPath,2);
            //文件保存全路径
            string fileFullName = tmpPath + "\\" + fileName;
            byte[] arr = Convert.FromBase64String(base64Str);
            if (System.IO.File.Exists(fileFullName))
            {
                System.IO.File.Delete(fileFullName);
            }
            System.IO.File.WriteAllBytes(fileFullName, arr);
            Hashtable hs = new Hashtable();
            hs.Add("Code", "LABReportImageFTP");
            hs.Add("ParaType", "HOS");
            //获得ftp配置参数
            List<SYSParameter> ftps = EntityManager.FindAll<SYSParameter>(hs);
            if (ftps[0].ParaValue.Length > 0 && ftps[0].ParaValue[ftps[0].ParaValue.Length - 1] == '/')
            {
                reAddr = reAddr.Substring(1);
            }
            string fullPath = ftps[0].ParaValue + reAddr + fileName;
            LIS.File.Core.FileService fileService = new LIS.File.Core.FileService();
            string ret=fileService.Upload(ftps[0].ParaValue, fileFullName, fileName, reAddr);
            System.IO.File.Delete(fileFullName);
            if (ret!="")
            {
                return "-1^"+ ret;
            }
            return fullPath;
        }

        /// <summary>
        /// 把FTP文件转换得到Base64串
        /// </summary>
        /// <param name="ftpPath">ftp文件全路径</param>
        /// <param name="passive">ftp模式</param>
        /// <returns></returns>
        [WebMethod]
        public string GetFtpFileBase64(string ftpPath, bool passive = false)
        {
            bool verify = InterfaceWhiteList.Verify("LIS.BLL.WebService.LISFileService.GetFtpFileBase64", "把FTP文件转换得到Base64串");
            if (ftpPath == null || ftpPath == "")
            {
                return "";
            }
            try
            {
                string sourcePath = @"C:\TRAK\TMP";
                if (!Directory.Exists(@"C:\TRAK"))
                {
                    Directory.CreateDirectory(@"C:\TRAK");
                }
                if (!Directory.Exists(sourcePath))
                {
                    Directory.CreateDirectory(sourcePath);
                }
                string aLastName = ftpPath.Substring(ftpPath.LastIndexOf("/") + 1, (ftpPath.Length - ftpPath.LastIndexOf("/") - 1));
                string localName = sourcePath + "\\" + aLastName;
                if (System.IO.File.Exists(localName))
                {
                    System.IO.File.Delete(localName);
                }
                LIS.File.Core.FileService fileService = new LIS.File.Core.FileService();
                fileService.Download(ftpPath, localName, passive);
                //DownloadFTP(ftpPath, localName, passive);
                if (System.IO.File.Exists(localName))
                {
                    string retStr = File2Base64Str(localName);
                    System.IO.File.Delete(localName);
                    return retStr;
                }
            }
            catch (Exception ex)
            {
                LIS.Core.Util.LogUtils.WriteExceptionLog("FTP文件转Base64串异常", ex);
            }
            //返回结果
            return "";
        }

服务包装如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Threading;
using System.Text;
using LIS.Model.Entity;
using System.Reflection;
using LIS.Model.Bussiness;
using System.Net;
using System.IO;

namespace LIS.BLL.WebService
{

    ///<summary  NoteObject="Class">
    /// [功能描述:检验上传文件到服务器服务] <para/>
    /// [创建者:zlz] <para/>
    /// [创建时间:2020年4月13日] <para/>
    ///<说明>
    ///  [说明:[功能描述:检验上传文件到服务器服务]<para/>
    ///</说明>
    ///<修改记录>
    ///    [修改时间:本次修改时间]<para/>
    ///    [修改内容:本次修改内容]<para/>
    ///</修改记录>
    ///<修改记录>
    ///    [修改时间:本次修改时间]<para/>
    ///    [修改内容:本次修改内容]<para/>
    ///</修改记录>
    ///</summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    //若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 
    // [System.Web.Script.Services.ScriptService]
    public class LISUpFileService : System.Web.Services.WebService
    {

        public LISUpFileService()
        {

            //如果使用设计的组件,请取消注释以下行 
            //InitializeComponent(); 
        }

        /// <summary>
        /// 上传文件到网站,成功返回空,失败返回原因
        /// </summary>
        /// <param name="fileBase64Str">文件的Base64串</param>
        /// <param name="fileName">文件名称</param>
        /// <param name="remotePath">相对路径,基于网站根目录下的FileService文件夹</param>
        /// <returns></returns>
        [WebMethod]
        public string Upload(string fileBase64Str, string fileName, string remotePath = "")
        {
            LIS.Core.Util.LogUtils.WriteDebugLog("数据:"+fileBase64Str+ " 文件名:"+fileName+ "相对路径"+remotePath);
            try
            {
                //专门配置的文件路径
                string FileServicePath = System.Configuration.ConfigurationSettings.AppSettings["FileServicePath"];
                //根路径
                string rootPath = HttpRuntime.AppDomainAppPath.ToString() + "FileService";
                if(FileServicePath!=null&& FileServicePath!="")
                {
                    rootPath = FileServicePath;
                }
                //创建根目录
                if (!Directory.Exists(rootPath))
                {
                    Directory.CreateDirectory(rootPath);
                }
                //目录不存在就创建
                string remoteAdd = "";
                if (remotePath != "")
                {
                    string[] remoteArr = remotePath.Split('/');
                    for (int i = 0; i < remoteArr.Length; i++)
                    {
                        if (remoteArr[i] == "")
                        {
                            continue;
                        }
                        remoteAdd += "\\" + remoteArr[i];
                        if (!Directory.Exists(rootPath + remoteAdd))
                        {
                            Directory.CreateDirectory(rootPath + remoteAdd);
                        }
                    }
                }
                //文件保存全路径
                string fileFullName = rootPath + remoteAdd + "\\" + fileName;
                byte[] arr = Convert.FromBase64String(fileBase64Str);
                if(System.IO.File.Exists(fileFullName))
                {
                    System.IO.File.Delete(fileFullName);
                }
                System.IO.File.WriteAllBytes(fileFullName, arr);
                //返回结果
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 同步文件到网站,成功返回空,失败返回原因
        /// </summary>
        /// <param name="fileBase64Str">文件的Base64串</param>
        /// <param name="fileName">文件名称</param>
        /// <param name="key">秘钥</param>
        /// <param name="remotePath">相对路径,基于网站根目录</param>
        /// <returns></returns>
        [WebMethod]
        public string SyncFile(string fileBase64Str, string fileName,string key, string remotePath = "")
        {
            LIS.Core.Util.LogUtils.WriteDebugLog("数据:" + fileBase64Str + " 文件名:" + fileName + "相对路径" + remotePath);
            try
            {
                if(key!="xxxx")
                {
                    return "密码验证不通过!";
                }
                if(remotePath=="")
                {
                    return "不允许往根目录同步文件!";
                }
                if(!fileName.ToLower().Contains(".json"))
                {
                    return "不允许同步非json文件!";
                }
                //根路径
                string rootPath = HttpRuntime.AppDomainAppPath.ToString();
                //创建根目录
                if (!Directory.Exists(rootPath))
                {
                    Directory.CreateDirectory(rootPath);
                }
                //目录不存在就创建
                string remoteAdd = "";
                if (remotePath != "")
                {
                    string[] remoteArr = remotePath.Split('/');
                    for (int i = 0; i < remoteArr.Length; i++)
                    {
                        if (remoteArr[i] == "")
                        {
                            continue;
                        }
                        if(remoteAdd=="")
                        {
                            remoteAdd += remoteArr[i];
                        }
                        else
                        {
                            remoteAdd += "\\" + remoteArr[i];
                        }
                        if (!Directory.Exists(rootPath + remoteAdd))
                        {
                            Directory.CreateDirectory(rootPath + remoteAdd);
                        }
                    }
                }
                //文件保存全路径
                string fileFullName = rootPath + remoteAdd + "\\" + fileName;
                byte[] arr = Convert.FromBase64String(fileBase64Str);
                if (System.IO.File.Exists(fileFullName))
                {
                    System.IO.File.Delete(fileFullName);
                }
                System.IO.File.WriteAllBytes(fileFullName, arr);
                //返回结果
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 移动文件
        /// </summary>
        /// <param name="currentFilename">当前全路径</param>
        /// <param name="newFilename">新的全路径</param>
        /// <returns></returns>
        [WebMethod]
        public string ReName(string currentFilename, string newFilename)
        {
            try
            {
                //根路径
                string rootPath = HttpRuntime.AppDomainAppPath.ToString() + "FileService";
                currentFilename = currentFilename.Replace("/FileService", ""+(char)0);
                currentFilename = currentFilename.Split((char)0)[1];
                currentFilename = currentFilename.Replace('/','\\').Replace("\\\\","\\");
                newFilename = newFilename.Replace("/FileService", "" + (char)0);
                newFilename = newFilename.Split((char)0)[1];
                newFilename = newFilename.Replace('/', '\\').Replace("\\\\", "\\");

                string curFileFullName = rootPath + currentFilename;
                string newFileFullName= rootPath + newFilename;
                //尝试创建目录
                string remoteAdd = "";
                if (newFilename != "")
                {
                    string[] remoteArr = newFilename.Split('\\');
                    for (int i = 0; i < remoteArr.Length-1; i++)
                    {
                        if (remoteArr[i] == "")
                        {
                            continue;
                        }
                        remoteAdd += "\\" + remoteArr[i];
                        if (!Directory.Exists(rootPath + remoteAdd))
                        {
                            Directory.CreateDirectory(rootPath + remoteAdd);
                        }
                    }
                }
                if (System.IO.File.Exists(curFileFullName))
                {
                    System.IO.File.Move(curFileFullName, newFileFullName);
                }
                else
                {
                    return "源文件不存在!"+ curFileFullName;
                }
                //返回结果
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="fileName">文件全路径</param>
        /// <returns></returns>
        [WebMethod]
        public string Delete(string fileName)
        {
            try
            {
                //根路径
                string rootPath = HttpRuntime.AppDomainAppPath.ToString() + "FileService";
                fileName = fileName.Replace("/FileService", "" + (char)0);
                fileName = fileName.Split((char)0)[1];
                fileName = fileName.Replace('/', '\\').Replace("\\\\", "\\");
                string curFileFullName = rootPath + fileName;
                if (System.IO.File.Exists(curFileFullName))
                {
                    System.IO.File.Delete(curFileFullName);
                }
                else
                {
                    return "删除文件不存在!" + curFileFullName;
                }
                //返回结果
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

    }

}

文件服务操作api部分

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.ServiceModel;

namespace LIS.File.Core
{
    ///<summary  NoteObject="Class">
    /// [功能描述:检验文件服务,提供文件操作服务] <para/>
    /// [创建者:zlz] <para/>
    /// [创建时间:2020年04月13日] <para/>
    ///<说明>
    ///  [说明:检验文件服务,提供文件操作服务]<para/>
    ///</说明>
    ///<修改记录>
    ///    [修改时间:本次修改时间]<para/>
    ///    [修改内容:本次修改内容]<para/>
    ///</修改记录>
    ///<修改记录>
    ///    [修改时间:本次修改时间]<para/>
    ///    [修改内容:本次修改内容]<para/>
    ///</修改记录>
    ///</summary>
    public class FileService : IFileService
    {
        /// <summary>
        /// 上传文件到文件服务
        /// </summary>
        /// <param name="serverPath">服务地址,如果是FTP就是FTP带密码的地址,如果是SFTP就是SFTP地址,如果是网站就是检验service/asmx/wbsDHCLISUpFileServiceHandler.asmx地址</param>
        /// <param name="fileFullName">文件带路径的全名</param>
        /// <param name="fileNewName">文件上传到服务器的新名称</param>
        /// <param name="remotePath">相对路径</param>
        /// <returns>空成功,非空返回失败原因</returns>
        public string Upload(string serverPath, string fileFullName, string fileNewName, string remotePath = "")
        {
            try
            {
                string ret = "";
                //普通ftp模式
                if (serverPath.ToLower().Contains("ftp://"))
                {
                    //创建帮助类
                    BaseFtpService ftp = new BaseFtpService(serverPath, remotePath);
                    //上传图片
                    ftp.Upload(fileFullName, fileNewName);
                    if (FileServiceFlags.Err != "")
                    {
                        ret = FileServiceFlags.Err;
                        FileServiceFlags.Err = "";
                    }
                    return ret;
                }
                //检验http模式
                else if (serverPath.ToLower().Contains("http://") || serverPath.ToLower().Contains("https://"))
                {
                    BasicHttpBinding bind1 = new BasicHttpBinding();
                    if (serverPath.ToLower().Contains("https://"))
                    {
                        //类似浏览器确认证书合法方法的绑定
                        ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidationCallback;
                        bind1 = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                    }
                    bind1.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas();
                    bind1.ReaderQuotas.MaxArrayLength = int.MaxValue;
                    bind1.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                    bind1.MaxReceivedMessageSize = int.MaxValue;
                    bind1.OpenTimeout = new TimeSpan(5000);
                    EndpointAddress endpointAddress = new EndpointAddress(GetFileServiceAddr(serverPath));
                    LISUpFileServiceSoapClient client = new LISUpFileServiceSoapClient(bind1, endpointAddress);
                    string fileBase64 = File2Base64Str(fileFullName);
                    System.IO.FileInfo fi = new System.IO.FileInfo(fileFullName);
                    string fileName = fi.Name;
                    if (fileNewName != "")
                    {
                        fileName = fileNewName;
                    }
                    return client.Upload(fileBase64, fileName, remotePath);
                }
                //sftp模式
                else
                {
                    return "-1^不支持的文件服务模式!";
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 上传文件到文件服务
        /// </summary>
        /// <param name="serverPath">服务地址,如果是FTP就是FTP带密码的地址,如果是SFTP就是SFTP地址,如果是网站就是检验service/asmx/wbsDHCLISUpFileServiceHandler.asmx地址</param>
        /// <param name="fileFullName">文件带路径的全名</param>
        /// <param name="fileNewName">文件上传到服务器的新名称</param>
        /// <param name="remotePath">相对路径</param>
        /// <returns>空成功,非空返回失败原因</returns>
        public string SyncFile(string serverPath, string fileFullName, string fileNewName, string remotePath = "")
        {
            if (remotePath == "")
            {
                return "不允许往根目录同步文件!";
            }
            try
            {
                string ret = "";
                if (serverPath.ToLower().Contains("http://") || serverPath.ToLower().Contains("https://"))
                {
                    string dealServerPath = serverPath.Replace("//", "" + (char)(0));
                    string ipPort = dealServerPath.Split((char)(0))[1].Split('/')[0];
                    string ip = ipPort.Split(':')[0];
                    if (ip == "localhost" || ip == "127.0.0.1")
                    {
                        return "";
                    }
                    if (GetIpv4() == ip)
                    {
                        return "";
                    }
                    BasicHttpBinding bind1 = new BasicHttpBinding();
                    if (serverPath.ToLower().Contains("https://"))
                    {
                        //类似浏览器确认证书合法方法的绑定
                        ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidationCallback;
                        bind1 = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                    }
                    bind1.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas();
                    bind1.ReaderQuotas.MaxArrayLength = int.MaxValue;
                    bind1.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                    bind1.MaxReceivedMessageSize = int.MaxValue;
                    bind1.OpenTimeout = new TimeSpan(5000);
                    EndpointAddress endpointAddress = new EndpointAddress(GetFileServiceAddr(serverPath));
                    LISUpFileServiceSoapClient client = new LISUpFileServiceSoapClient(bind1, endpointAddress);
                    string fileBase64 = File2Base64Str(fileFullName);
                    System.IO.FileInfo fi = new System.IO.FileInfo(fileFullName);
                    string fileName = fi.Name;
                    if (fileNewName != "")
                    {
                        fileName = fileNewName;
                    }
                    return client.SyncFile(fileBase64, fileName, "xxxx", remotePath);
                }
                return ret;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 获得当前机器的ip4串
        /// </summary>
        /// <returns></returns>
        private string GetIpv4()
        {
            System.Net.IPAddress[] arrIPAddresses = System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName());
            foreach (System.Net.IPAddress ip in arrIPAddresses)
            {
                if (ip.AddressFamily.Equals(System.Net.Sockets.AddressFamily.InterNetwork))
                {
                    return ip.ToString();
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 上传文件到文件服务
        /// </summary>
        /// <param name="serverPath">服务地址,如果是FTP就是FTP带密码的地址,如果是SFTP就是SFTP地址,如果是网站就是检验service/asmx/wbsDHCLISUpFileServiceHandler.asmx地址</param>
        /// <param name="stream">文件流</param>
        /// <param name="fileNewName">文件上传到服务器的新名称</param>
        /// <param name="remotePath">相对路径</param>
        /// <returns>空成功,非空返回失败原因</returns>
        public string Upload(string serverPath, System.IO.Stream stream, string fileNewName, string remotePath = "")
        {
            try
            {
                string ret = "";
                //普通ftp模式
                if (serverPath.ToLower().Contains("ftp://"))
                {
                    //创建帮助类
                    BaseFtpService ftp = new BaseFtpService(serverPath, remotePath);
                    //上传图片
                    ftp.Upload(stream, fileNewName);
                    if (FileServiceFlags.Err != "")
                    {
                        ret = FileServiceFlags.Err;
                        FileServiceFlags.Err = "";
                    }
                    return ret;
                }
                //检验http模式
                else if (serverPath.ToLower().Contains("http://") || serverPath.ToLower().Contains("https://"))
                {
                    BasicHttpBinding bind1 = new BasicHttpBinding();
                    if (serverPath.ToLower().Contains("https://"))
                    {
                        //类似浏览器确认证书合法方法的绑定
                        ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidationCallback;
                        bind1 = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                    }
                    bind1.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas();
                    bind1.ReaderQuotas.MaxArrayLength = int.MaxValue;
                    bind1.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                    bind1.MaxReceivedMessageSize = int.MaxValue;
                    bind1.OpenTimeout = new TimeSpan(5000);
                    EndpointAddress endpointAddress = new EndpointAddress(GetFileServiceAddr(serverPath));
                    LISUpFileServiceSoapClient client = new LISUpFileServiceSoapClient(bind1, endpointAddress);
                    string fileBase64 = Stream2Base64Str(stream);
                    string fileName = fileNewName;
                    return client.Upload(fileBase64, fileName, remotePath);
                }
                //sftp模式
                else
                {
                    return "-1^不支持的文件服务模式!";
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 从服务下载文件
        /// </summary>
        /// <param name="fileServerFullPath">文件在服务的全路径</param>
        /// <param name="fileFullName">文件本地保存的全路径</param>
        public void Download(string fileServerFullPath, string fileFullName, bool passive = false)
        {
            FileServiceFlags.Err = "";
            try
            {
                //普通ftp模式
                if (fileServerFullPath.ToLower().Contains("ftp://"))
                {
                    //创建帮助类
                    BaseFtpService ftp = new BaseFtpService(fileServerFullPath, "");
                    //上传图片
                    ftp.Download(fileFullName, fileServerFullPath, passive);
                }
                //检验http模式
                else if (fileServerFullPath.ToLower().Contains("http://") || fileServerFullPath.ToLower().Contains("https://"))
                {
                    System.IO.FileStream outputStream = null;
                    System.IO.Stream responseStream = null;
                    try
                    {
                        HttpWebRequest request = null;
                        if (fileServerFullPath.ToLower().StartsWith("https", StringComparison.OrdinalIgnoreCase))
                        {
                            request = WebRequest.Create(fileServerFullPath) as HttpWebRequest;
                            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                            request.ProtocolVersion = HttpVersion.Version11;
                            // 这里设置了协议类型。
                            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                            request.KeepAlive = false;
                            ServicePointManager.CheckCertificateRevocationList = true;
                            ServicePointManager.DefaultConnectionLimit = 100;
                            ServicePointManager.Expect100Continue = false;
                        }
                        else
                        {
                            request = WebRequest.Create(fileServerFullPath) as HttpWebRequest;
                        }
                        request.Timeout = 5000;
                        HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                        if (response == null)
                        {
                            return;
                        }
                        responseStream = response.GetResponseStream();
                        if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(fileFullName)))
                        {
                            System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(fileFullName));
                        }
                        if (System.IO.File.Exists(fileFullName))
                        {
                            System.IO.File.Delete(fileFullName);
                        }
                        //创建本地文件写入流 
                        outputStream = new System.IO.FileStream(fileFullName, System.IO.FileMode.Create);
                        long cl = response.ContentLength;
                        int bufferSize = 2048;
                        int readCount;
                        byte[] buffer = new byte[bufferSize];
                        readCount = responseStream.Read(buffer, 0, bufferSize);
                        while (readCount > 0)
                        {
                            outputStream.Write(buffer, 0, readCount);
                            readCount = responseStream.Read(buffer, 0, bufferSize);
                        }
                    }
                    catch (Exception ex)
                    {
                        FileServiceFlags.Err = ex.Message;
                    }
                    finally
                    {
                        if (outputStream != null)
                        {
                            outputStream.Close();
                        }
                        if (responseStream != null)
                        {
                            responseStream.Flush();
                            responseStream.Close();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                FileServiceFlags.Err = ex.Message;
            }
        }


        /// <summary>
        /// 从服务下载文件
        /// </summary>
        /// <param name="fileServerFullPath">文件在服务的全路径</param>
        public System.IO.Stream DownloadStream(string fileServerFullPath, bool passive = false)
        {
            FileServiceFlags.Err = "";
            try
            {
                //普通ftp模式
                if (fileServerFullPath.ToLower().Contains("ftp://"))
                {
                    //创建帮助类
                    BaseFtpService ftp = new BaseFtpService(fileServerFullPath, "");
                    //下载流
                    return ftp.DownloadStream(fileServerFullPath, passive);
                }
                //检验http模式
                else if (fileServerFullPath.ToLower().Contains("http://") || fileServerFullPath.ToLower().Contains("https://"))
                {
                    try
                    {
                        HttpWebRequest request = null;
                        if (fileServerFullPath.ToLower().StartsWith("https", StringComparison.OrdinalIgnoreCase))
                        {
                            request = WebRequest.Create(fileServerFullPath) as HttpWebRequest;
                            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                            request.ProtocolVersion = HttpVersion.Version11;
                            // 这里设置了协议类型。
                            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                            request.KeepAlive = false;
                            ServicePointManager.CheckCertificateRevocationList = true;
                            ServicePointManager.DefaultConnectionLimit = 100;
                            ServicePointManager.Expect100Continue = false;
                        }
                        else
                        {
                            request = WebRequest.Create(fileServerFullPath) as HttpWebRequest;
                        }
                        request.Timeout = 5000;
                        HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                        if (response == null)
                        {
                            return null;
                        }
                        System.IO.Stream responseStream = response.GetResponseStream();
                        return responseStream;
                    }
                    catch (Exception ex)
                    {
                        FileServiceFlags.Err = ex.Message;
                    }
                }
                //sftp模式
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                FileServiceFlags.Err = ex.Message;
            }
            return null;
        }

        /// <summary>
        /// 修改文件名
        /// </summary>
        /// <param name="serverPath">服务地址,如果是FTP就是FTP带密码的地址,如果是SFTP就是SFTP地址,如果是网站就是检验service/asmx/wbsDHCLISUpFileServiceHandler.asmx地址</param>
        /// <param name="currentFilename">当前文件名</param>
        /// <param name="newFilename">修改的文件名</param>
        /// <param name="remotePath">相对路径</param>
        public void ReName(string serverPath, string currentFilename, string newFilename, string remotePath = "")
        {
            FileServiceFlags.Err = "";
            try
            {
                //普通ftp模式
                if (serverPath.ToLower().Contains("ftp://"))
                {
                    //创建帮助类
                    BaseFtpService ftp = new BaseFtpService(serverPath, remotePath);
                    //上传图片
                    ftp.ReName(currentFilename, newFilename);
                }
                //检验http模式
                else if (serverPath.ToLower().Contains("http://") || serverPath.ToLower().Contains("https://"))
                {
                    BasicHttpBinding bind1 = new BasicHttpBinding();
                    if (serverPath.ToLower().Contains("https://"))
                    {
                        //类似浏览器确认证书合法方法的绑定
                        ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidationCallback;
                        bind1 = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                    }
                    bind1.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas();
                    bind1.ReaderQuotas.MaxArrayLength = int.MaxValue;
                    bind1.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                    bind1.MaxReceivedMessageSize = int.MaxValue;
                    bind1.OpenTimeout = new TimeSpan(5000);
                    EndpointAddress endpointAddress = new EndpointAddress(GetFileServiceAddr(serverPath));
                    LISUpFileServiceSoapClient client = new LISUpFileServiceSoapClient(bind1, endpointAddress);
                    string ret = client.ReName(serverPath + remotePath + currentFilename, serverPath + remotePath + newFilename);
                    if (ret != "")
                    {
                        FileServiceFlags.Err = ret;
                    }
                }

            }
            catch (Exception ex)
            {
                FileServiceFlags.Err = ex.Message;
            }
        }

        /// <summary>
        /// 移动文件
        /// </summary>
        /// <param name="currentFullFilename">原路径</param>
        /// <param name="newFullFilename">新路径</param>
        public void Move(string currentFullFilename, string newFullFilename)
        {
            FileServiceFlags.Err = "";
            try
            {
                //普通ftp模式
                if (currentFullFilename.ToLower().Contains("ftp://"))
                {
                    //创建帮助类
                    BaseFtpService ftp = new BaseFtpService("", "");
                    //上传图片
                    ftp.Move(currentFullFilename, newFullFilename);
                }
                //检验http模式
                else if (currentFullFilename.ToLower().Contains("http://") || currentFullFilename.ToLower().Contains("https://"))
                {

                    BasicHttpBinding bind1 = new BasicHttpBinding();
                    if (currentFullFilename.ToLower().Contains("https://"))
                    {
                        //类似浏览器确认证书合法方法的绑定
                        ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidationCallback;
                        bind1 = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                    }
                    bind1.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas();
                    bind1.ReaderQuotas.MaxArrayLength = int.MaxValue;
                    bind1.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                    bind1.MaxReceivedMessageSize = int.MaxValue;
                    bind1.OpenTimeout = new TimeSpan(5000);
                    EndpointAddress endpointAddress = new EndpointAddress(GetFileServiceAddr(currentFullFilename));
                    LISUpFileServiceSoapClient client = new LISUpFileServiceSoapClient(bind1, endpointAddress);
                    string ret = client.ReName(currentFullFilename, newFullFilename);
                    if (ret != "")
                    {
                        FileServiceFlags.Err = ret;
                    }
                }
            }
            catch (Exception ex)
            {
                FileServiceFlags.Err = ex.Message;
            }
        }

        /// <summary>
        /// 删除服务器上的文件
        /// </summary>
        /// <param name="fileServerFullPath">文件在服务的全路径</param>
        public void Delete(string fileServerFullPath)
        {
            FileServiceFlags.Err = "";
            try
            {
                //普通ftp模式
                if (fileServerFullPath.ToLower().Contains("ftp://"))
                {
                    //创建帮助类
                    BaseFtpService ftp = new BaseFtpService("", "");
                    //上传图片
                    ftp.Delete(fileServerFullPath);
                }
                //检验http模式
                else if (fileServerFullPath.ToLower().Contains("http://") || fileServerFullPath.ToLower().Contains("https://"))
                {
                    BasicHttpBinding bind1 = new BasicHttpBinding();
                    if (fileServerFullPath.ToLower().Contains("https://"))
                    {
                        //类似浏览器确认证书合法方法的绑定
                        ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidationCallback;
                        bind1 = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                    }
                    bind1.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas();
                    bind1.ReaderQuotas.MaxArrayLength = int.MaxValue;
                    bind1.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                    bind1.MaxReceivedMessageSize = int.MaxValue;
                    bind1.OpenTimeout = new TimeSpan(5000);
                    EndpointAddress endpointAddress = new EndpointAddress(GetFileServiceAddr(fileServerFullPath));
                    LISUpFileServiceSoapClient client = new LISUpFileServiceSoapClient(bind1, endpointAddress);
                    string ret = client.Delete(fileServerFullPath);
                    if (ret != "")
                    {
                        FileServiceFlags.Err = ret;
                    }
                }
            }
            catch (Exception ex)
            {
                FileServiceFlags.Err = ex.Message;
            }
        }

        /// <summary>             
        /// 将文件转换为Base64串     
        /// </summary>             
        /// <param name="path">文件地址</param>             
        /// <returns>转换后的byte数组</returns>             
        public string File2Base64Str(string path)
        {
            if (!System.IO.File.Exists(path))
            {
                return "";
            }
            System.IO.FileInfo fi = new System.IO.FileInfo(path);
            byte[] buff = new byte[fi.Length];
            System.IO.FileStream fs = null;
            try
            {
                fs = fi.OpenRead();
                fs.Read(buff, 0, Convert.ToInt32(fs.Length));

                return Convert.ToBase64String(buff);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
            }
            return "";
        }

        /// <summary>             
        /// 将文件流转换为Base64串     
        /// </summary>             
        /// <param name="stream">文件流</param>             
        /// <returns>转换后的byte数组</returns>             
        public string Stream2Base64Str(System.IO.Stream stream)
        {
            byte[] buff = new byte[stream.Length];
            try
            {
                stream.Read(buff, 0, buff.Length);
                return Convert.ToBase64String(buff);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return "";
        }

        /// <summary>
        /// 通过服务地址得到webservice服务地址
        /// </summary>
        /// <param name="serverPath"></param>
        /// <returns></returns>
        private string GetFileServiceAddr(string serverPath)
        {
            string[] arr = serverPath.Split('/');
            string webHead = "";
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i].ToLower() == "fileservice")
                {
                    break;
                }
                webHead = webHead + arr[i] + "/";
            }
            return webHead + "service/asmx/wbsDHCLISUpFileServiceHandler.asmx";

        }

        /// <summary>
        /// 回调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            //总是接受  
            return true;
        }

        /// <summary>
        /// 该方法用于验证服务器证书是否合法,当然可以直接返回true来表示验证永远通过。服务器证书具体内容在参数certificate中。可根据个人需求验证.该方法在request.GetResponse()时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="sslPolicyErrors"></param>
        /// <returns></returns>
        public static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }
}


要透过现象看本质,把文件服务操作的共性提取出来。反而操作文件服务简化了,你管他是ftp还是http呢,按实际情况配地址就是了。由api按地址协议给你进行操作。

又是一个优美设计,借助对Base64串和Webservice的理解,及ftp操作理解。既兼容了ftp,也支持了http,同时方便img加载使用。同时比ftp可靠和安全性更高。奈何产品重视不够。

重要设计有:
通用码表

浏览器和EXE交互

打印设计

模板化导出Excel

M绘图

监听程序

事务托管

死循环监控

Excel导入

跨库执行M

消息转换器

负载客户端

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小乌鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值