using Microsoft.Extensions.Logging;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
namespace AIMSExtension
{
///
/// ftp下载类
///
public class FTPTransmission
{
///
/// 记录所有要下载的文件路径及下载到本地的路径
///
public static List ListFileDirectory = new List();
///
/// 记录当前文件路径及下载到本地的路径
///
public static List nowListFileDirectory = new List();
///
/// 记录要下载的文件路径及下载到本地的路径
///
public struct ftpFileDirectory
{
///
/// 要下载的文件路径
///
public string ftpPath;
///
/// 下载到本地的路径
///
public string localPath;
///
/// 文件名
///
public string filename;
///
/// 文件大小
///
public long filelength;
///
/// MD5码
///
public string MD5Hash;
}
///
/// 设置ftp服务器的命令,并获取文件和文件夹,以及文件夹内的子文件
///
/// FTP地址路径
/// 要发送到FTP服务器的命令
/// 用户名
/// 密码
///
public static string[] ftp(string ftpads, string type, string username, string password)
{
WebResponse webresp = null;
StreamReader ftpFileListReader = null;
FtpWebRequest ftpRequest = null;
try
{
ftpRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpads));
ftpRequest.Method = type;
ftpRequest.Credentials = new NetworkCredential(username,
password);
webresp = ftpRequest.GetResponse();
ftpFileListReader = new StreamReader(webresp.GetResponseStream(), Encoding.UTF8);//new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default)
StringBuilder str = new StringBuilder();
string line = ftpFileListReader.ReadLine();
while (line != null)
{
str.Append(line);
str.Append("\n");
line = ftpFileListReader.ReadLine();
}
string[] fen = str.ToString().Split('\n');
return fen;
}
catch (Exception)
{
//MessageBox.Show("更新失败! 请检查网络或者FTP用户名与口令!");
Environment.Exit(0);
return null;
}
}
///
/// 递归实现获取ftp目录下所有文件及文件夹以及文件夹内的子文件
///
/// FTP路径
/// 保存的本地路径
/// 用户名
/// 密码
public static void downftp(string ftpads, string downloadDir, string username, string password, Hashtable htUpdateFile)
{
try
{
downloadDir = downloadDir.Replace("\\\\", "\\");
string ftpdir = ftpads;
string[] fullname = ftp(ftpads, WebRequestMethods.Ftp.ListDirectoryDetails, username, password);
if (fullname == null) return;
string[] onlyname = ftp(ftpads, WebRequestMethods.Ftp.ListDirectory, username, password);
if (onlyname == null) return;
if (!Directory.Exists(downloadDir))
{
Directory.CreateDirectory(downloadDir);
}
foreach (string names in fullname)
{
//判断是否具有文件夹标识
if (names.Contains(""))
{
string olname = names.Split(new string[] { "" },
StringSplitOptions.None)[1].Trim();
downftp(ftpads + "/" + olname, downloadDir + "\\" + olname, username, password, htUpdateFile);
}
else
{
foreach (string onlynames in onlyname)
{
if (string.IsNullOrEmpty(onlynames.Trim()) || string.IsNullOrEmpty(names.Trim())) break;
if (names.Contains(" " + onlynames))
{
//download(downloadDir + "\\" + onlynames, ftpads + "/" + onlynames, username, password);
var fd = new ftpFileDirectory();
fd.ftpPath = ftpads + "/" + onlynames.ToString();
fd.localPath = downloadDir + "\\" + onlynames.ToString();
fd.localPath = fd.localPath.Replace("\\\\", "\\");
fd.filename = onlynames.ToString();
fd.filelength = GetFileSize(fd.ftpPath, username, password);
for (int i = 0; i < htUpdateFile.Count; i++)
{
string[] fileArray = (string[])htUpdateFile[i];
if (fd.filename == fileArray[0])
{
fd.MD5Hash = fileArray[1];
break;
}
}
ListFileDirectory.Add(fd);
break;
}
}
}
}
}
catch (Exception ex)
{
PublicMethod.WriteLog(ex);
Environment.Exit(0);
}
}
///
/// 递归实现获取ftp目录下所有文件及文件夹以及文件夹内的子文件
///
/// FTP路径
/// 保存的本地路径
/// 用户名
/// 密码
public static void downNow(string ftpads)
{
try
{
DirectoryInfo theFolder = new DirectoryInfo(ftpads);
printAllFile(theFolder);
}
catch (Exception)
{
//MessageBox.Show("获取目录失败+downftp" + ex.ToString());
Environment.Exit(0);
}
}
public static void printAllFile(DirectoryInfo di)
{
FileInfo[] fiArray = di.GetFiles();
DirectoryInfo[] diArray = di.GetDirectories();
foreach (FileInfo NextFile in fiArray)
{
try
{
if (NextFile.Name.Contains("AutoUpdate") || NextFile.Name.Contains("KHD_ICUEMR")) continue;
var fd = new ftpFileDirectory();
fd.ftpPath = NextFile.DirectoryName + "\\" + NextFile.Name.ToString();
fd.filename = NextFile.Name.ToString();
fd.filelength = NextFile.Length;
fd.MD5Hash = GetMD5HashFromFile(fd.ftpPath);
nowListFileDirectory.Add(fd);
}
catch (Exception)
{
continue;
}
}
foreach (DirectoryInfo inst in diArray)
{
printAllFile(inst);
}
}
///
/// 单个文件下载
///
/// 保存文件的本地路径
/// 下载文件的FTP路径
/// 用户名
/// 密码
public static void download(string adss, string ftpadss, string username, string password)
{
try
{
//FileMode常数确定如何打开或创建文件,指定操作系统应创建新文件。
FtpWebRequest downRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpadss));
downRequest.Credentials = new NetworkCredential(username, password);
//设置要发送到 FTP 服务器的命令
downRequest.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)downRequest.GetResponse();
Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
if (readCount > 0)
{
//FileMode.Create如果文件已存在,它将被改写
FileStream outputStream = new FileStream(adss, FileMode.Create);
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
outputStream.Close();
}
ftpStream.Close();
response.Close();
}
catch (Exception)
{
}
}
///
/// 获得文件大小
///
///
///
public static long GetFileSize(string ftpadss, string username, string password)
{
FtpWebRequest downRequest = null;
long fileSize = 0;
try
{
downRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpadss));
downRequest.Credentials = new NetworkCredential(username, password);
downRequest.Method = WebRequestMethods.Ftp.GetFileSize;
FtpWebResponse response = (FtpWebResponse)downRequest.GetResponse();
fileSize = response.ContentLength;
response.Close();
}
catch (Exception e)
{
downRequest.GetLogger().LogError(e, "更新失败");
}
return fileSize;
}
///
/// FTP获取文件的MD5码
///
/// 传入的文件名(含路径及后缀名)
///
public static string FTPGetMD5HashFromFile(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)
{
return "";
//throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
}
}
///
/// 获取文件的MD5码
///
/// 传入的文件名(含路径及后缀名)
///
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)
{
//throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
return "";
}
}
#region 上传文件 UploadFile
///
/// 上传文件
///
/// 需要上传的文件
/// 目标路径
/// ftp地址
/// ftp用户名
/// ftp密码
public static void UploadFile(FileInfo fileinfo, string targetDir, string hostname, string username, string password)
{
//1. check target
string target;
if (targetDir.Trim() == "")
{
return;
}
target = Guid.NewGuid().ToString(); //使用临时文件名
string URI = "FTP://" + hostname + "/" + targetDir + "/" + target;
if (targetDir == "PDF" || targetDir == "JPG")
{
URI = "FTP://" + hostname + "/" + target;
}
///WebClient webcl = new WebClient();
System.Net.FtpWebRequest ftp = GetRequest(URI, username, password);
try
{
System.Net.FtpWebRequest ftpdel = GetRequest(("FTP://" + hostname + "/" + fileinfo.Name), username, password);
ftpdel.Method = System.Net.WebRequestMethods.Ftp.DeleteFile; //删除
ftpdel.GetResponse();
}
catch (Exception)
{
}
ftp = GetRequest(URI, username, password);
//设置FTP命令 设置所要执行的FTP命令,
//ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;//假设此处为显示指定路径下的文件列表
ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
//指定文件传输的数据类型
ftp.UseBinary = true;
ftp.UsePassive = true;
//告诉ftp文件大小
ftp.ContentLength = fileinfo.Length;
//缓冲大小设置为2KB
const int BufferSize = 2048;
byte[] content = new byte[BufferSize - 1 + 1];
int dataRead;
//打开一个文件流 (System.IO.FileStream) 去读上传的文件
using (FileStream fs = fileinfo.OpenRead())
{
try
{
//把上传的文件写入流
using (Stream rs = ftp.GetRequestStream())
{
do
{
//每次读文件流的2KB
dataRead = fs.Read(content, 0, BufferSize);
rs.Write(content, 0, dataRead);
} while (!(dataRead < BufferSize));
rs.Close();
}
}
catch (Exception) { }
finally
{
fs.Close();
}
}
ftp = null;
//设置FTP命令
ftp = GetRequest(URI, username, password);
ftp.Method = System.Net.WebRequestMethods.Ftp.Rename; //改名
ftp.RenameTo = fileinfo.Name;
try
{
ftp.GetResponse();
}
catch (Exception ex)
{
ftp = GetRequest(URI, username, password);
ftp.Method = System.Net.WebRequestMethods.Ftp.DeleteFile; //删除
ftp.GetResponse();
throw ex;
}
finally
{
//fileinfo.Delete();
}
// 可以记录一个日志 "上传" + fileinfo.FullName + "上传到" + "FTP://" + hostname + "/" + targetDir + "/" + fileinfo.Name + "成功." );
ftp = null;
#region
/*****
*FtpWebResponse
* ****/
//FtpWebResponse ftpWebResponse = (FtpWebResponse)ftp.GetResponse();
#endregion
}
public static void UploadFile(FileInfo fileinfo, string targetDir, string hostname, string username, string password, string FileName)
{
//1. check target
string target;
if (targetDir.Trim() == "")
{
return;
}
target = Guid.NewGuid().ToString(); //使用临时文件名
string URI = "FTP://" + hostname + "/" + targetDir + "/" + target;
if (targetDir == "PDF" || targetDir == "JPG")
{
URI = "FTP://" + hostname + "/" + target;
}
///WebClient webcl = new WebClient();
System.Net.FtpWebRequest ftp = GetRequest(URI, username, password);
try
{
System.Net.FtpWebRequest ftpdel = GetRequest(("FTP://" + hostname + "/" + FileName), username, password);
ftpdel.Method = System.Net.WebRequestMethods.Ftp.DeleteFile; //删除
ftpdel.GetResponse();
}
catch (Exception)
{
}
ftp = GetRequest(URI, username, password);
//设置FTP命令 设置所要执行的FTP命令,
//ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;//假设此处为显示指定路径下的文件列表
ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
//指定文件传输的数据类型
ftp.UseBinary = true;
ftp.UsePassive = true;
//告诉ftp文件大小
ftp.ContentLength = fileinfo.Length;
//缓冲大小设置为2KB
const int BufferSize = 2048;
byte[] content = new byte[BufferSize - 1 + 1];
int dataRead;
//打开一个文件流 (System.IO.FileStream) 去读上传的文件
using (FileStream fs = fileinfo.OpenRead())
{
try
{
//把上传的文件写入流
using (Stream rs = ftp.GetRequestStream())
{
do
{
//每次读文件流的2KB
dataRead = fs.Read(content, 0, BufferSize);
rs.Write(content, 0, dataRead);
} while (!(dataRead < BufferSize));
rs.Close();
}
}
catch (Exception) { }
finally
{
fs.Close();
}
}
ftp = null;
//设置FTP命令
ftp = GetRequest(URI, username, password);
ftp.Method = System.Net.WebRequestMethods.Ftp.Rename; //改名
ftp.RenameTo = FileName;
try
{
ftp.GetResponse();
}
catch (Exception ex)
{
ftp = GetRequest(URI, username, password);
ftp.Method = System.Net.WebRequestMethods.Ftp.DeleteFile; //删除
ftp.GetResponse();
throw ex;
}
finally
{
//fileinfo.Delete();
}
// 可以记录一个日志 "上传" + fileinfo.FullName + "上传到" + "FTP://" + hostname + "/" + targetDir + "/" + FileName + "成功." );
ftp = null;
#region
/*****
*FtpWebResponse
* ****/
//FtpWebResponse ftpWebResponse = (FtpWebResponse)ftp.GetResponse();
#endregion
}
private static FtpWebRequest GetRequest(string URI, string username, string password)
{
//根据服务器信息FtpWebRequest创建类的对象
FtpWebRequest result = (FtpWebRequest)FtpWebRequest.Create(URI);
//提供身份验证信息
result.Credentials = new System.Net.NetworkCredential(username, password);
//设置请求完成之后是否保持到FTP服务器的控制连接,默认值为true
result.KeepAlive = false;
return result;
}
#endregion
}
}