AIMS/AIMSExtension/FTPTransmission.cs
2023-08-16 22:32:16 +08:00

568 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// ftp下载类
/// </summary>
public class FTPTransmission
{
/// <summary>
/// 记录所有要下载的文件路径及下载到本地的路径
/// </summary>
public static List<ftpFileDirectory> ListFileDirectory = new List<ftpFileDirectory>();
/// <summary>
/// 记录当前文件路径及下载到本地的路径
/// </summary>
public static List<ftpFileDirectory> nowListFileDirectory = new List<ftpFileDirectory>();
/// <summary>
/// 记录要下载的文件路径及下载到本地的路径
/// </summary>
public struct ftpFileDirectory
{
/// <summary>
/// 要下载的文件路径
/// </summary>
public string ftpPath;
/// <summary>
/// 下载到本地的路径
/// </summary>
public string localPath;
/// <summary>
/// 文件名
/// </summary>
public string filename;
/// <summary>
/// 文件大小
/// </summary>
public long filelength;
/// <summary>
/// MD5码
/// </summary>
public string MD5Hash;
}
/// <summary>
/// 设置ftp服务器的命令并获取文件和文件夹以及文件夹内的子文件
/// </summary>
/// <param name="ftpads">FTP地址路径</param>
/// <param name="type">要发送到FTP服务器的命令</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 递归实现获取ftp目录下所有文件及文件夹以及文件夹内的子文件
/// </summary>
/// <param name="ftpads">FTP路径</param>
/// <param name="downloadDir">保存的本地路径</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
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)
{
//判断是否具有文件夹标识<DIR>
if (names.Contains("<DIR>"))
{
string olname = names.Split(new string[] { "<DIR>" },
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);
}
}
/// <summary>
/// 递归实现获取ftp目录下所有文件及文件夹以及文件夹内的子文件
/// </summary>
/// <param name="ftpads">FTP路径</param>
/// <param name="downloadDir">保存的本地路径</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
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);
}
}
/// <summary>
/// 单个文件下载
/// </summary>
/// <param name="adss">保存文件的本地路径</param>
/// <param name="ftpadss">下载文件的FTP路径</param>
/// <param name="username">用户名</param>
/// <param name="password">密码</param>
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)
{
}
}
/// <summary>
/// 获得文件大小
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
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;
}
/// <summary>
/// FTP获取文件的MD5码
/// </summary>
/// <param name="fileName">传入的文件名(含路径及后缀名)</param>
/// <returns></returns>
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);
}
}
/// <summary>
/// 获取文件的MD5码
/// </summary>
/// <param name="fileName">传入的文件名(含路径及后缀名)</param>
/// <returns></returns>
public static string GetMD5HashFromFile(string fileName)
{
try
{
FileStream file = new FileStream(fileName, System.IO.FileMode.Open);
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
file.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
catch (Exception)
{
//throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
return "";
}
}
#region UploadFile
/// <summary>
/// 上传文件
/// </summary>
/// <param name="fileinfo">需要上传的文件</param>
/// <param name="targetDir">目标路径</param>
/// <param name="hostname">ftp地址</param>
/// <param name="username">ftp用户名</param>
/// <param name="password">ftp密码</param>
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
}
}