Temp/FtpHelper.cs
2026-06-15 13:22:23 +08:00

644 lines
27 KiB
C#
Raw Permalink 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;
using xaf.logger;
namespace quarto.cbo.util
{
public class FtpHelper
{
public static Ftp GetFtp(string hostIP, string userName, string password)
{
return new Ftp(hostIP, userName, password);
}
}
public class Ftp
{
private string host = null;
private string user = null;
private string pass = null;
private FtpWebRequest ftpRequest = null;
private FtpWebResponse ftpResponse = null;
private Stream ftpStream = null;
private int bufferSize = 2048;
private string currentDirectory = null;
public List<string> Files { get; set; }
public LogManager logManager = null;
public bool IsThrowException = false;
/* Construct Object */
public Ftp(string hostIP, string userName, string password) { logManager = LogManager.GetInstance(); Files = new List<string>(); host = hostIP; user = userName; pass = password; }
private bool HandleException(Exception ex)
{
logManager.Log(ex.ToString(), LogLevel.ERROR, this);
return IsThrowException;
}
/* Download File */
public void download(string remoteFile, string localFile)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(remoteFile));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Thread.Sleep(2000);
/* Get the FTP Server's Response Stream */
ftpStream = ftpResponse.GetResponseStream();
/* Open a File Stream to Write the Downloaded File */
FileStream localFileStream = new FileStream(localFile, FileMode.Create);
/* Buffer for the Downloaded Data */
byte[] byteBuffer = new byte[bufferSize];
int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
/* Download the File by Writing the Buffered Data Until the Transfer is Complete */
try
{
while (bytesRead > 0)
{
localFileStream.Write(byteBuffer, 0, bytesRead);
bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex) { if (HandleException(ex)) throw; }
finally
{
/* Resource Cleanup */
localFileStream.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
}
catch (Exception ex) { if (HandleException(ex)) throw; }
return;
}
/* Upload File */
public void upload(string remoteFile, string localFile)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(remoteFile));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
/* Establish Return Communication with the FTP Server */
ftpStream = ftpRequest.GetRequestStream();
/* Open a File Stream to Read the File for Upload */
FileStream localFileStream = new FileStream(localFile, FileMode.Open);
/* Buffer for the Downloaded Data */
byte[] byteBuffer = new byte[bufferSize];
int bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
/* Upload the File by Sending the Buffered Data Until the Transfer is Complete */
try
{
while (bytesSent != 0)
{
ftpStream.Write(byteBuffer, 0, bytesSent);
bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex) { if (HandleException(ex)) throw; }
finally
{
/* Resource Cleanup */
localFileStream.Close();
ftpStream.Close();
ftpRequest = null;
}
}
catch (Exception ex) { if (HandleException(ex)) throw; }
return;
}
/* Delete File */
public void delete(string deleteFile)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + Uri.EscapeDataString(deleteFile));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Thread.Sleep(2000);
/* Resource Cleanup */
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex) { if (HandleException(ex)) throw; }
return;
}
/* Rename File */
public void rename(string currentFileNameAndPath, string newFileName)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + Uri.EscapeDataString(currentFileNameAndPath));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.Rename;
/* Rename the File */
ftpRequest.RenameTo = newFileName;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Thread.Sleep(2000);
/* Resource Cleanup */
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex) { if (HandleException(ex)) throw; }
return;
}
/* Create a New Directory on the FTP Server */
public void createDirectory(string newDirectory)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + Uri.EscapeDataString(newDirectory));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Thread.Sleep(2000);
/* Resource Cleanup */
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex) { if (HandleException(ex)) throw; }
return;
}
/* Get the Date/Time a File was Created */
public string getFileCreatedDateTime(string fileName)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(fileName));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.GetDateTimestamp;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Thread.Sleep(2000);
/* Establish Return Communication with the FTP Server */
ftpStream = ftpResponse.GetResponseStream();
/* Get the FTP Server's Response Stream */
StreamReader ftpReader = new StreamReader(ftpStream);
/* Store the Raw Response */
string fileInfo = null;
/* Read the Full Response Stream */
try { fileInfo = ftpReader.ReadToEnd(); }
catch (Exception ex) { if (HandleException(ex)) throw; }
finally
{
/* Resource Cleanup */
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
/* Return File Created Date Time */
return fileInfo;
}
catch (Exception ex) { if (HandleException(ex)) throw; }
/* Return an Empty string Array if an Exception Occurs */
return "";
}
/* Get the Size of a File */
public string getFileSize(string fileName)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(fileName));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Thread.Sleep(2000);
/* Establish Return Communication with the FTP Server */
ftpStream = ftpResponse.GetResponseStream();
/* Get the FTP Server's Response Stream */
StreamReader ftpReader = new StreamReader(ftpStream);
/* Store the Raw Response */
string fileInfo = null;
/* Read the Full Response Stream */
try { while (ftpReader.Peek() != -1) { fileInfo = ftpReader.ReadToEnd(); } }
catch (Exception ex) { if (HandleException(ex)) throw; }
finally
{
/* Resource Cleanup */
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
/* Return File Size */
return fileInfo;
}
catch (Exception ex) { if (HandleException(ex)) throw; }
/* Return an Empty string Array if an Exception Occurs */
return "";
}
/* List Directory Contents File/Folder Name Only */
public string[] directoryListSimple(string directory)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(directory));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = false;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Thread.Sleep(2000);
/* Establish Return Communication with the FTP Server */
ftpStream = ftpResponse.GetResponseStream();
/* Get the FTP Server's Response Stream */
StreamReader ftpReader = new StreamReader(ftpStream);
/* Store the Raw Response */
string directoryRaw = null;
/* Read Each Line of the Response and Append a Pipe to Each Line for Easy Parsing */
try { while (ftpReader.Peek() != -1) { directoryRaw += ftpReader.ReadLine() + "|"; } }
catch (Exception ex) { if (HandleException(ex)) throw; }
finally
{
/* Resource Cleanup */
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
if (directoryRaw == null) return null;
/* Return the Directory Listing as a string Array by Parsing 'directoryRaw' with the Delimiter you Append (I use | in This Example) */
try { string[] directoryList = directoryRaw.Split("|".ToCharArray()); return GetFileNames(directoryList); }
catch (Exception ex) { if (HandleException(ex)) throw; }
}
catch (Exception ex) { if (HandleException(ex)) throw; }
/* Return an Empty string Array if an Exception Occurs */
return new string[] { "" };
}
private static string[] GetFileNames(string[] directoryList)
{
if (directoryList == null || directoryList.Length == 0) return null;
List<string> l = new List<string>();
foreach (string value in directoryList)
{
if (string.IsNullOrEmpty(value)) continue;
if (!value.Contains("/")) l.Add(value);
else
l.Add(value.Substring(value.LastIndexOf('/') + 1, value.Length - value.LastIndexOf('/') - 1));
}
return l.ToArray();
}
/* List Directory Contents in Detail (Name, Size, Created, etc.) */
public string[] directoryListDetailed(string directory)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + Uri.EscapeDataString(directory));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = false;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Thread.Sleep(2000);
/* Establish Return Communication with the FTP Server */
ftpStream = ftpResponse.GetResponseStream();
/* Get the FTP Server's Response Stream */
StreamReader ftpReader = new StreamReader(ftpStream);
/* Store the Raw Response */
string directoryRaw = null;
/* Read Each Line of the Response and Append a Pipe to Each Line for Easy Parsing */
try { while (ftpReader.Peek() != -1) { directoryRaw += ftpReader.ReadLine() + "|"; } }
catch (Exception ex) { if (HandleException(ex)) throw; }
finally
{
/* Resource Cleanup */
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
if (directoryRaw == null) return null;
/* Return the Directory Listing as a string Array by Parsing 'directoryRaw' with the Delimiter you Append (I use | in This Example) */
try { string[] directoryList = directoryRaw.Split("|".ToCharArray()); return directoryList; }
catch (Exception ex) { if (HandleException(ex)) throw; }
}
catch (Exception ex) { if (HandleException(ex)) throw; }
/* Return an Empty string Array if an Exception Occurs */
return new string[] { "" };
}
//進入當前目錄
public void ChangeFolder(string directory)
{
if (string.IsNullOrEmpty(directory) || directory == "/")
{
currentDirectory = null;
return;
}
if (directory.StartsWith("/")) directory = directory.Substring(1, directory.Length - 1);
currentDirectory += (string.IsNullOrEmpty(currentDirectory) ? null : "/") + directory;
}
//list當前目錄
public string[] directoryListDetailed()
{
return directoryListDetailed(currentDirectory);
}
//list當前目錄
public string[] directoryListSimple()
{
return directoryListSimple(currentDirectory);
}
//list對象有區分是否目錄還是文件
public List<FtpItem> List()
{
List<FtpItem> list = new List<FtpItem>();
FtpItem fi;
logManager.Log("----------------------------------directoryListSimple----------------------------------", LogLevel.INFO, this);
string[] ns = directoryListSimple();
logManager.Log("----------------------------------directoryListDetailed----------------------------------", LogLevel.INFO, this);
string[] dirs = directoryListDetailed();
if (ns == null || ns.Length == 0) return list;
foreach (string n in ns)
{
logManager.Log("directoryListSimple:" + n, LogLevel.INFO, this);
if (string.IsNullOrEmpty(n)) continue;
fi = new FtpItem();
fi.Name = n;
if (dirs.Where(x => x.Contains(n)).Where(x => x.Contains("<DIR>") || x.StartsWith("d")).Count() > 0)
{
fi.IsFolder = true;
}
list.Add(fi);
}
return list;
}
//刪除文件
public void DeleteFile(string fileName)
{
delete(currentDirectory + "/" + fileName);
}
//刪除文件夾,如果下面有內容,要一級一級的刪除
public void DeleteFolderRecursively(string remoteFolder)
{
ChangeFolder(null);//回到根目錄
if (!string.IsNullOrEmpty(remoteFolder))
ChangeFolder(remoteFolder);
List<FtpItem> fis = List();
if (fis == null || fis.Count == 0)
{
ChangeFolder(null);//回到根目錄
deleteFolder(remoteFolder);
return;
}
string tempCurrentDirectory = currentDirectory;
foreach (FtpItem fi in fis)
{
ChangeFolder(null);//回到根目錄
ChangeFolder(tempCurrentDirectory);//回到首次進入目錄
if (fi.IsFolder)
{
DeleteFolderRecursively(currentDirectory + "/" + fi.Name);
}
else
{
DeleteFile(fi.Name);
}
}
//最后再刪除本身這個文件夾
ChangeFolder(null);//回到根目錄
deleteFolder(remoteFolder);
}
//刪除文件夾
public void deleteFolder(string deleteDirectory)
{
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + Uri.EscapeDataString(deleteDirectory));
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(user, pass);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Thread.Sleep(2000);
/* Resource Cleanup */
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex) { if (HandleException(ex)) throw; }
return;
}
//下載整個目錄下的內容
public int DownloadFiles(string remoteFolder, string localFolder)
{
return DownloadFiles(remoteFolder, localFolder, null);
}
//下載整個目錄下的內容
public int DownloadFiles(string remoteFolder, string localFolder, string passFilePath)
{
if (!Directory.Exists(localFolder))
{
Directory.CreateDirectory(localFolder);
}
ChangeFolder(null);//回到根目錄
if (!string.IsNullOrEmpty(remoteFolder))
ChangeFolder(remoteFolder);
logManager.Log("----------------------------------Download Folder:" + remoteFolder, LogLevel.INFO, this);
List<FtpItem> fis = List();
if (fis == null || fis.Count == 0) return 0;
string tempCurrentDirectory = currentDirectory;
string[] passFilePaths = null;
if (!string.IsNullOrEmpty(passFilePath)) passFilePaths = passFilePath.Split(new char[] { ';', ',' });
if (passFilePaths != null && passFilePaths.Length > 0)
passFilePaths = passFilePaths.Where(x => !string.IsNullOrEmpty(x)).ToArray();
string tempRemoteFolder = null;
int totalFiles = 0; // 累计下载的文件总数
foreach (FtpItem fi in fis)
{
tempRemoteFolder = remoteFolder + "/" + fi.Name;
if (passFilePaths != null && passFilePaths.Length > 0 && passFilePaths.Any(x => tempRemoteFolder.Trim().ToUpper().StartsWith(x.Trim().ToUpper() + "/")))
{
logManager.Log(">>>>>>>>>>>Pass Folder:" + tempRemoteFolder, LogLevel.INFO, this);
continue;
}
ChangeFolder(null);//回到根目錄
ChangeFolder(tempCurrentDirectory);//回到首次進入目錄
if (fi.IsFolder)
{
logManager.Log("DownloadFolder:" + tempRemoteFolder, LogLevel.INFO, this);
totalFiles += DownloadFiles(tempRemoteFolder, localFolder + "\\" + fi.Name);
}
else
{
logManager.Log("DownloadFiles:" + tempRemoteFolder, LogLevel.INFO, this);
download(tempRemoteFolder, localFolder + "\\" + fi.Name);
Files.Add(localFolder + "\\" + fi.Name);
totalFiles++; // 每下载一个文件计数加1
}
}
return totalFiles;
}
// 获取远程目录下的文件总数(不下载)
public int GetFileCount(string remoteFolder)
{
return GetFileCount(remoteFolder, null);
}
// 获取远程目录下的文件总数,支持跳过指定路径
public int GetFileCount(string remoteFolder, string passFilePath)
{
ChangeFolder(null); // 回到根目录
if (!string.IsNullOrEmpty(remoteFolder))
ChangeFolder(remoteFolder);
logManager.Log("----------------------------------Get File Count Folder:" + remoteFolder, LogLevel.INFO, this);
List<FtpItem> fis = List();
if (fis == null || fis.Count == 0) return 0;
string tempCurrentDirectory = currentDirectory;
string[] passFilePaths = null;
if (!string.IsNullOrEmpty(passFilePath))
passFilePaths = passFilePath.Split(new char[] { ';', ',' });
if (passFilePaths != null && passFilePaths.Length > 0)
passFilePaths = passFilePaths.Where(x => !string.IsNullOrEmpty(x)).ToArray();
int totalFiles = 0;
foreach (FtpItem fi in fis)
{
string tempRemoteFolder = remoteFolder + "/" + fi.Name;
if (passFilePaths != null && passFilePaths.Length > 0 && passFilePaths.Any(x => tempRemoteFolder.Trim().ToUpper().StartsWith(x.Trim().ToUpper() + "/")))
{
logManager.Log(">>>>>>>>>>>Pass Folder (counting skipped):" + tempRemoteFolder, LogLevel.INFO, this);
continue;
}
ChangeFolder(null);
ChangeFolder(tempCurrentDirectory);
if (fi.IsFolder)
{
// 递归统计子文件夹
totalFiles += GetFileCount(tempRemoteFolder, passFilePath);
}
else
{
totalFiles++;
}
}
return totalFiles;
}
}
public class FtpItem
{
public bool IsFolder { get; set; }
public string Name { get; set; }
}
}