远古时期,在谷歌还是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可靠和安全性更高。奈何产品重视不够。
重要设计有:
通用码表