Ftp 文件操作封装


/****************************************************************************************
** 作者: 许丽勤
** 时间: 2017/12/1 15:22:59
** 版本: V1.0.0
** CLR: 4.0.30319.42000
** GUID: 29056e4b-0c09-4fa1-b6a2-69b33d943737
** 机器名: DESKTOP-ECII567
** 描述: 尚未编写描述
****************************************************************************************/

using Manjinba.Communication.Common.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Manjinba.Communication.Common.Utils
{
public class FtpOperationUtil
{
//remote指Ftp服务

public static string ftpRemotePath;

#region 变量属性
/// <summary>
/// Ftp服务器ip
/// </summary>
public static string FtpServerIP = ConfigUtil.GetConfigStr("FtpServerIP");
/// <summary>
/// Ftp 指定用户名
/// </summary>
public static string FtpUserID = ConfigUtil.GetConfigStr("FtpUserID");
/// <summary>
/// Ftp 指定用户密码
/// </summary>
public static string FtpPassword = ConfigUtil.GetConfigStr("FtpPassword");
/// <summary>
/// 根目录
/// </summary>
public static string rootPath = ConfigUtil.GetConfigStr("RootFtpPath");
/// <summary>
/// PC版本目录文件
/// </summary>
public static string PcVersionPath = ConfigUtil.GetConfigStr("PcVersionPath");
/// <summary>
/// PC发布版本目录
/// </summary>
public static string PcPublishPath = ConfigUtil.GetConfigStr("PcPublishPath");
/// <summary>
/// Android版本目录文件
/// </summary>
public static string AndroidVersionPath = ConfigUtil.GetConfigStr("AndroidVersionPath");
/// <summary>
/// Android发布版本目录
/// </summary>
public static string AndroidPublishPath = ConfigUtil.GetConfigStr("AndroidPublishPath")?.Trim('/').Trim('\');
/// <summary>
/// iOS版本目录文件
/// </summary>
public static string iOSVersionPath = ConfigUtil.GetConfigStr("iOSVersionPath")?.Trim('/').Trim('\');
/// <summary>
/// iOS发布版本目录
/// </summary>
public static string iOSPublishPath = ConfigUtil.GetConfigStr("iOSPublishPath")?.Trim('/').Trim('\');
/// <summary>
/// Ftp访问Uri
/// </summary>
public static string ftpURI = "ftp://" + FtpServerIP + "/";
/// <summary>
/// FTP存储基本地址
/// </summary>
public static string ftpBasePath = ftpURI + rootPath + "/";
#endregion

#region 按默认规则创建多层文件夹
/// <summary>
/// 按默认规则创建多层文件夹
/// </summary>
public static void MakeMultilayerDir(string defaultRegularPath)
{
try
{
if (!string.IsNullOrWhiteSpace(defaultRegularPath))
{
defaultRegularPath = defaultRegularPath.TrimStart('/').TrimEnd('/');
}

#region 判断每一层文件夹是否存在,不存在一层层创建

var everyFilePath = (defaultRegularPath).Replace(ftpURI, "").Split('/');
var currentPath = string.Empty;
foreach (var path in everyFilePath)
{
currentPath = (currentPath + "/" + path).TrimStart('/');
if (!DirectoryExist(currentPath))
{
MakeDir(currentPath);
}
continue;
}
#endregion
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("MakeMultilayerDir:" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("MakeMultilayerDir:" + e.Message.ToString() + e.StackTrace);
}
}
#endregion

#region 判断文件夹是否存在
/// <summary>
/// 判断当前目录下指定的子目录是否存在
/// </summary>
/// <param name="remoteDirectoryName">指定的目录名</param>
public static bool DirectoryExist(string remoteDirectoryName)
{
try
{
var parentPath = remoteDirectoryName.Substring(0, remoteDirectoryName.LastIndexOf('/') == -1 ? 0 : remoteDirectoryName.LastIndexOf('/'));
var childPath = remoteDirectoryName.Substring(remoteDirectoryName.LastIndexOf('/') + 1);
string[] dirList = GetDirectoryList(parentPath);
foreach (string str in dirList)
{
if (str.Trim() == childPath.Trim())
{
return true;
}
}
return false;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("DirectoryExist:" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("DirectoryExist:" + e.Message.ToString() + e.StackTrace);
return false;
}

}

/// <summary>
/// 判断当前目录下指定的文件是否存在
/// </summary>
/// <param name="RemoteFileName">远程文件名</param>
public static bool FileExist(string RemoteFileName)
{
try
{
string[] fileList = GetFileList("*.*");
foreach (string str in fileList)
{
if (str.Trim() == RemoteFileName.Trim())
{
return true;
}
}
return false;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("FileExist" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FileExist" + e.Message.ToString() + e.StackTrace);
return false;
}
}
#endregion

#region 创建文件夹
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="dirName"></param>
public static void MakeDir(string dirName)
{
FtpWebRequest reqFTP;
try
{
// dirName = name of the directory to create.
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + dirName));
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("MakeDir" + ftpURI + dirName);
reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();

ftpStream.Close();
response.Close();
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("MakeDir" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("MakeDir" + e.Message.ToString() + e.StackTrace);
}
}
#endregion

#region 获取文件大小
/// <summary>
/// 获取指定文件大小
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public static long GetFileSize(string filename)
{
FtpWebRequest reqFTP;
long fileSize = 0;
try
{
//reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + filename));
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(filename));
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetFileSize Single" + filename);
reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
fileSize = response.ContentLength;

ftpStream.Close();
response.Close();
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetFileSize Single" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetFileSize Single" + e.Message.ToString() + e.StackTrace);
}
return fileSize;
}
#endregion

#region 检查文件是否完整
/// <summary>
/// 检查文件是否完整
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public static bool CheckFileIsComplete(string filename)
{
FtpWebRequest reqFTP, ftpsize;
Stream ftpStream = null;
FtpWebResponse response = null;
var outputStream = new MemoryStream();
try
{
if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
{
throw new Exception("ftp下载目标服务器地址未设置!");
}
//Uri uri = new Uri(ftpURI + "/" + remoteFileName);
Uri uri = new Uri(filename);
ftpsize = (FtpWebRequest)FtpWebRequest.Create(uri);
ftpsize.UseBinary = true;

reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
ftpsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
long totalBytes = re.ContentLength;
re.Close();

reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
response = (FtpWebResponse)reqFTP.GetResponse();
ftpStream = response.GetResponseStream();

long totalDownloadedByte = 0;
int bufferSize = 1024;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
totalDownloadedByte = readCount + totalDownloadedByte;
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
//ftpStream.Flush();
ftpStream.Close();
response.Close();
outputStream.Position = 0;
var streamMd5 = GetStreamMd5(outputStream);
var fileMd5 = filename.Substring(filename.LastIndexOf('/') + 1, 32);

return fileMd5.Equals(streamMd5, StringComparison.CurrentCultureIgnoreCase);
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("文件:" + filename + "错误:" + e.Message.ToString() + e.StackTrace);
return false;
}
finally
{
if (ftpStream != null)
{
ftpStream.Close();
}
if (response != null)
{
response.Close();
}
}
}
#endregion

#region 上传文件到FTP服务器

/// <summary>
/// 上传文件到FTP服务器(单次上传或续传)
/// </summary>
/// <param name="localFullFileName">本地文件全路径名称</param>
/// <param name="remoteFilepath">远程文件所在文件夹路径</param>
/// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
/// <returns></returns>
public static string FtpUploadFileOrBroken(Stream fileStream, string localFileName, string remoteFilepath)
{
FtpWebRequest reqFTP;
string newFileName = string.Empty;
// 按默认规则创建多层文件夹
MakeMultilayerDir(remoteFilepath);
//var fullRemoteFilePath = ftpURI + "/" + remoteFilepath.TrimStart('/').TrimEnd('/'); //需要加 rootPath
var fullRemoteFilePath = remoteFilepath.TrimStart('/').TrimEnd('/'); //需要加 rootPath
long allbye = fileStream.Length;
if (localFileName.IndexOf("#") == -1)
{
newFileName = RemoveSpaces(localFileName);
}
else
{
newFileName = localFileName.Replace("#", "#");
newFileName = RemoveSpaces(newFileName);
}
long startfilesize = GetFileSize(newFileName, remoteFilepath);
//if (startfilesize >= allbye)
//{
// //return remoteFilepath + "/" + newFileName;
// return remoteFilepath; //(含 ftp:// 的绝对路径不含文件名)
//}
long startbye = startfilesize;

Uri uri = new Uri(fullRemoteFilePath);
// 根据uri创建FtpWebRequest对象
reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri + "/" + localFileName);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FtpUploadFileOrBroken" + uri + "/" + localFileName);
// ftp用户名和密码
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
// 默认为true,连接不会被关闭
// 在一个命令之后被执行
reqFTP.KeepAlive = false;
// 指定执行什么命令
reqFTP.Method = startfilesize == 0 ? WebRequestMethods.Ftp.UploadFile : WebRequestMethods.Ftp.AppendFile;
// 指定数据传输类型
reqFTP.UseBinary = true;
// 上传文件时通知服务器文件的大小
reqFTP.ContentLength = allbye;
int buffLength = 2048;// 缓冲大小设置为2kb
byte[] buff = new byte[buffLength];
// 打开一个文件流 (System.IO.FileStream) 去读上传的文件
//FileStream fs = fileStream.;
Stream strm = null;
try
{
// 把上传的文件写入流
strm = reqFTP.GetRequestStream();
// 每次读文件流的8kb
fileStream.Seek(0, 0);
int contentLen = fileStream.Read(buff, 0, buffLength);
// 流内容没有结束
while (contentLen != 0)
{
// 把内容从file stream 写入 upload stream
strm.Write(buff, 0, contentLen);
contentLen = fileStream.Read(buff, 0, buffLength);
startbye += contentLen;
}
// 关闭两个流
strm.Close();
//fileStream.Close();
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("FtpUploadFileOrBroken" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FtpUploadFileOrBroken" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
finally
{
//if (fileStream != null)
//{
// fileStream.Close();
//}
if (strm != null)
{
strm.Close();
}
}
//return uri.AbsolutePath.TrimStart('/').TrimEnd('/') + "/" + newFileName; // 不含 ftp:// 的相对路径含文件名
//return ftpURI + uri.AbsolutePath.TrimStart('/').TrimEnd('/'); // (含 ftp:// 的绝对路径不含文件名)
return uri.AbsolutePath.TrimStart('/').TrimEnd('/'); // (不含ftp://192.168.4.25)
}

/// <summary>
/// 上传文件到FTP服务器(单次上传或续传)
/// </summary>
/// <param name="localFullFileName">本地文件全路径名称</param>
/// <param name="remoteFilepath">远程文件所在文件夹路径</param>
/// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
/// <returns></returns>
public static string FtpUploadFile(Stream fileStream, string localFileName, string remoteFilepath)
{
FtpWebRequest reqFTP;
string newFileName = string.Empty;
// 按默认规则创建多层文件夹
MakeMultilayerDir(remoteFilepath);
//var fullRemoteFilePath = ftpURI + "/" + remoteFilepath.TrimStart('/').TrimEnd('/'); //需要加 rootPath
var fullRemoteFilePath = remoteFilepath.TrimStart('/').TrimEnd('/'); //需要加 rootPath
long allbye = fileStream.Length;
if (localFileName.IndexOf("#") == -1)
{
newFileName = RemoveSpaces(localFileName);
}
else
{
newFileName = localFileName.Replace("#", "#");
newFileName = RemoveSpaces(newFileName);
}
long startbye = 0;

Uri uri = new Uri(fullRemoteFilePath);
// 根据uri创建FtpWebRequest对象
reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri + "/" + localFileName);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FtpUploadFileOrBroken" + uri + "/" + localFileName);
// ftp用户名和密码
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
// 默认为true,连接不会被关闭
// 在一个命令之后被执行
reqFTP.KeepAlive = false;
// 指定执行什么命令
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
// 指定数据传输类型
reqFTP.UseBinary = true;
// 上传文件时通知服务器文件的大小
reqFTP.ContentLength = allbye;
int buffLength = 2048;// 缓冲大小设置为2kb
byte[] buff = new byte[buffLength];
// 打开一个文件流 (System.IO.FileStream) 去读上传的文件
//FileStream fs = fileStream.;
Stream strm = null;
try
{
// 把上传的文件写入流
strm = reqFTP.GetRequestStream();
// 每次读文件流的2kb
fileStream.Seek(0, 0);
int contentLen = fileStream.Read(buff, 0, buffLength);
// 流内容没有结束
while (contentLen != 0)
{
// 把内容从file stream 写入 upload stream
strm.Write(buff, 0, contentLen);
contentLen = fileStream.Read(buff, 0, buffLength);
startbye += contentLen;
}
// 关闭两个流
strm.Close();
//fileStream.Close();
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("FtpUploadFileOrBroken" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FtpUploadFileOrBroken" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
finally
{
//if (fileStream != null)
//{
// fileStream.Close();
//}
if (strm != null)
{
strm.Close();
}
}
//return uri.AbsolutePath.TrimStart('/').TrimEnd('/') + "/" + newFileName; // 不含 ftp:// 的相对路径含文件名
//return ftpURI + uri.AbsolutePath.TrimStart('/').TrimEnd('/'); // (含 ftp:// 的绝对路径不含文件名)
return uri.AbsolutePath.TrimStart('/').TrimEnd('/'); // (不含ftp://192.168.4.25)
}

/// <summary>
/// 上传文件到FTP服务器(单次上传或续传)
/// </summary>
/// <param name="fileStream">上传的文件流</param>
/// <param name="saveFileName">保存的文件名</param>
/// <param name="filePath">文件保存路径(保证所有文件保存在一个文件夹中)</param>
/// <returns></returns>
public static long UploadFileBlockOrBroken(Stream fileStream, string saveFileName, string filePath)
{
FtpWebRequest reqFTP;
string newFileName = string.Empty;
// 按默认规则创建多层文件夹
MakeMultilayerDir(filePath);
//var fullRemoteFilePath = ftpURI + filePath.TrimStart('/').TrimEnd('/'); //需要加 rootPath
var fullRemoteFilePath = filePath.TrimStart('/').TrimEnd('/'); //需要加 rootPath
long allbye = fileStream.Length;
if (saveFileName.IndexOf("#") == -1)
{
newFileName = RemoveSpaces(saveFileName);
}
else
{
newFileName = saveFileName.Replace("#", "#");
newFileName = RemoveSpaces(newFileName);
}
long startfilesize = GetFileSize(newFileName, filePath);
if (startfilesize >= allbye)
{
return startfilesize;
}
long startbye = startfilesize;

Uri uri = new Uri(fullRemoteFilePath);
// 根据uri创建FtpWebRequest对象
reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri + "/" + saveFileName);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("UploadFileBlockOrBroken" + uri + "/" + saveFileName);
// ftp用户名和密码
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
// 默认为true,连接不会被关闭
// 在一个命令之后被执行
reqFTP.KeepAlive = false;
// 指定执行什么命令
reqFTP.Method = startfilesize == 0 ? WebRequestMethods.Ftp.UploadFile : WebRequestMethods.Ftp.AppendFile;
// 指定数据传输类型
reqFTP.UseBinary = true;
// 上传文件时通知服务器文件的大小
reqFTP.ContentLength = allbye;
int buffLength = 2048;// 缓冲大小设置为2kb
byte[] buff = new byte[buffLength];
// 打开一个文件流 (System.IO.FileStream) 去读上传的文件
//FileStream fs = fileStream.;
Stream strm = null;
try
{
// 把上传的文件写入流
strm = reqFTP.GetRequestStream();
//strm = await reqFTP.GetRequestStreamAsync();
// 每次读文件流的8kb
fileStream.Seek(startfilesize, 0);
int contentLen = fileStream.Read(buff, 0, buffLength);
// 流内容没有结束
while (contentLen != 0)
{
// 把内容从file stream 写入 upload stream
strm.Write(buff, 0, contentLen);
contentLen = fileStream.Read(buff, 0, buffLength);
startbye += contentLen;
}
// 关闭两个流
strm.Close();
//fileStream.Close();
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("UploadFileBlockOrBroken" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("UploadFileBlockOrBroken" + e.Message.ToString() + e.StackTrace);
return 0L;
}
finally
{
//if (fileStream != null)
//{
// fileStream.Close();
//}
if (strm != null)
{
strm.Close();
}
}
return startfilesize + allbye;
}

/// <summary>
/// 去除空格
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private static string RemoveSpaces(string str)
{
try
{
string a = "";
CharEnumerator CEnumerator = str.GetEnumerator();
while (CEnumerator.MoveNext())
{
byte[] array = new byte[1];
array = System.Text.Encoding.ASCII.GetBytes(CEnumerator.Current.ToString());
int asciicode = (short)(array[0]);
if (asciicode != 32)
{
a += CEnumerator.Current.ToString();
}
}
string sdate = System.DateTime.Now.Year.ToString() + System.DateTime.Now.Month.ToString() + System.DateTime.Now.Day.ToString() + System.DateTime.Now.Hour.ToString()
+ System.DateTime.Now.Minute.ToString() + System.DateTime.Now.Second.ToString() + System.DateTime.Now.Millisecond.ToString();
return a.Split('.')[a.Split('.').Length - 2] + "." + a.Split('.')[a.Split('.').Length - 1];
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("RemoveSpaces" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("RemoveSpaces" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}

/// <summary>
/// 获取已上传文件大小
/// </summary>
/// <param name="filename">文件名称</param>
/// <param name="path">服务器文件路径</param>
/// <returns></returns>
public static long GetFileSize(string filename, string remoteFilepath)
{
long filesize = 0;
try
{
FtpWebRequest reqFTP;
FileInfo fi = new FileInfo(filename);
string uri;
if (remoteFilepath.Length == 0)
{
//uri = ftpURI + "/" + fi.Name;
uri = fi.Name;
}
else
{
//uri = ftpURI + "/" + remoteFilepath + "/" + fi.Name;
uri = remoteFilepath + "/" + fi.Name;
}
reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetFileSize" + uri);
reqFTP.KeepAlive = false;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);//用户,密码
reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
filesize = response.ContentLength;
return filesize;
}
//catch (Exception e)
catch
{
//LogHelper.GetLog(this).Error("GetFileSize" + e.Message.ToString());
//LogHelper.GetLog(this).Info("GetFileSize" + e.Message.ToString());
return 0;
}
}

#endregion

#region 下载文件 (流方式)

/// <summary>
/// 从FTP服务器下载文件,指定本地路径和本地文件名
/// </summary>
/// <param name="remoteFileName">远程文件名</param>
/// <param name="localFileName">保存本地的文件名(包含路径)</param>
/// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>
/// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
/// <returns>是否下载成功</returns>
public static Stream FtpDownload(string remoteFileName)
{
FtpWebRequest reqFTP, ftpsize;
Stream ftpStream = null;
FtpWebResponse response = null;
var outputStream = new MemoryStream();
try
{
if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
{
throw new Exception("ftp下载目标服务器地址未设置!");
}
//Uri uri = new Uri(ftpURI + "/" + remoteFileName);
Uri uri = new Uri(remoteFileName);
ftpsize = (FtpWebRequest)FtpWebRequest.Create(uri);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FtpDownload" + uri);
ftpsize.UseBinary = true;

reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FtpDownload" + uri);
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
reqFTP.Timeout = 120000;
reqFTP.UsePassive = true;
ftpsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
long totalBytes = re.ContentLength;
re.Close();

reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
response = (FtpWebResponse)reqFTP.GetResponse();
ftpStream = response.GetResponseStream();

long totalDownloadedByte = 0;
int bufferSize = 1024;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
totalDownloadedByte = readCount + totalDownloadedByte;
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
//ftpStream.Flush();
ftpStream.Close();
response.Close();
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("文件:" + remoteFileName + "错误:" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("文件:" + remoteFileName + "错误:" + e.Message.ToString() + e.StackTrace);
}
finally
{
if (ftpStream != null)
{
ftpStream.Close();
}
if (response != null)
{
response.Close();
}
}
return outputStream;
}

/// <summary>
/// 从FTP服务器下载文件,指定本地路径和本地文件名
/// </summary>
/// <param name="remoteFileName">远程文件名</param>
/// <param name="localFileName">保存本地的文件名(包含路径)</param>
/// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>
/// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
/// <returns>是否下载成功</returns>
public static async Task<Stream> FtpAsyncDownload(string remoteFileName)
{
FtpWebRequest reqFTP;
FtpWebResponse response = null;
var outputStream = new MemoryStream();
try
{
if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
{
throw new Exception("ftp下载目标服务器地址未设置!");
}
LogHelper.GetLog().Debug(remoteFileName);
Uri uri = new Uri(remoteFileName);
reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
LogHelper.GetLog().Debug(uri);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FtpDownload" + uri);
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = true;
reqFTP.Timeout = 120000;
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
response = await reqFTP.GetResponseAsync() as FtpWebResponse;
var ftpStream = response.GetResponseStream();
long totalDownloadedByte = 0;
int bufferSize = 1024;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
totalDownloadedByte = readCount + totalDownloadedByte;
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
//ftpStream.Flush();
ftpStream.Close();
response.Close();
return outputStream;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("文件:" + remoteFileName + "错误:" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("文件:" + remoteFileName + "错误:" + e.Message.ToString() + e.StackTrace);
return outputStream;
}
finally
{
if (response != null)
response.Close();
}
}

/// <summary>
/// 从FTP服务器下载文件,指定本地路径和本地文件名(支持断点下载)
/// </summary>
/// <param name="remoteFileName">远程文件名</param>
/// <param name="localFileName">保存本地的文件名(包含路径)</param>
/// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>
/// <param name="startPoint">已下载文件流大小</param>
/// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
/// <returns>是否下载成功</returns>
public static Stream FtpBrokenDownload(string remoteFileName, bool ifCredential, long startPoint, long endPoint)
{
FtpWebRequest reqFTP, ftpsize;
Stream ftpStream = null;
FtpWebResponse response = null;
var outputStream = new MemoryStream();
try
{
if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
{
throw new Exception("ftp下载目标服务器地址未设置!");
}
//Uri uri = new Uri(ftpURI + "/" + remoteFileName);
Uri uri = new Uri(remoteFileName);
ftpsize = (FtpWebRequest)FtpWebRequest.Create(uri);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FtpBrokenDownload" + uri);
ftpsize.UseBinary = true;
ftpsize.ContentOffset = startPoint;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FtpBrokenDownload" + uri);
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = true;
reqFTP.ContentOffset = startPoint;
if (ifCredential)//使用用户身份认证
{
ftpsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
}
ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
long totalBytes = re.ContentLength;
re.Close();
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
response = (FtpWebResponse)reqFTP.GetResponse();
ftpStream = response.GetResponseStream();
long totalDownloadedByte = 0;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
long leftCount = endPoint - startPoint + 1;
if (endPoint == 0)
{
leftCount = totalBytes;
}
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
totalDownloadedByte = readCount + totalDownloadedByte;
if (leftCount > 0)
{
if (leftCount < readCount)
{
outputStream.Write(buffer, 0, (int)leftCount);
}
else
{
outputStream.Write(buffer, 0, (int)readCount);
}
}
leftCount = leftCount - readCount;
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
ftpStream.Flush();
ftpStream.Close();
response.Close();
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("文件:" + remoteFileName + "错误:" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("文件:" + remoteFileName + "错误:" + e.Message.ToString() + e.StackTrace);
}
finally
{
if (ftpStream != null)
{
ftpStream.Close();
}
if (response != null)
{
response.Close();
}
}
return outputStream;
}

/// <summary>
/// 从FTP服务器异步下载文件,指定本地路径和本地文件名(支持断点下载)
/// </summary>
/// <param name="remoteFileName">远程文件名</param>
/// <param name="localFileName">保存本地的文件名(包含路径)</param>
/// <param name="ifCredential">是否启用身份验证(false:表示允许用户匿名下载)</param>
/// <param name="startPoint">已下载文件流大小</param>
/// <param name="updateProgress">报告进度的处理(第一个参数:总大小,第二个参数:当前进度)</param>
/// <returns>是否下载成功</returns>
public async static Task<Stream> FtpAsyncBrokenDownload(string remoteFileName, bool ifCredential, long startPoint, long endPoint)
{
FtpWebRequest reqFTP, ftpsize;
Stream ftpStream = null;
FtpWebResponse response = null;
var outputStream = new MemoryStream();
try
{
if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
{
throw new Exception("ftp下载目标服务器地址未设置!");
}
//Uri uri = new Uri(ftpURI + "/" + remoteFileName);
Uri uri = new Uri(remoteFileName);
ftpsize = (FtpWebRequest)FtpWebRequest.Create(uri);
ftpsize.UseBinary = true;
ftpsize.ContentOffset = startPoint;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = true;
reqFTP.ContentOffset = startPoint;
if (ifCredential)//使用用户身份认证
{
ftpsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
}
ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
long totalBytes = re.ContentLength;
re.Close();
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
response = await reqFTP.GetResponseAsync() as FtpWebResponse;
ftpStream = response.GetResponseStream();
long totalDownloadedByte = 0;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
long leftCount = endPoint - startPoint + 1;
if (endPoint == 0)
{
leftCount = totalBytes;
}
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
totalDownloadedByte = readCount + totalDownloadedByte;
if (leftCount > 0)
{
if (leftCount < readCount)
{
outputStream.Write(buffer, 0, (int)leftCount);
}
else
{
outputStream.Write(buffer, 0, (int)readCount);
}
}
leftCount = leftCount - readCount;
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
ftpStream.Flush();
ftpStream.Close();
response.Close();
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("文件:" + remoteFileName + "错误:" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("文件:" + remoteFileName + "错误:" + e.Message.ToString() + e.StackTrace);
}
finally
{
if (ftpStream != null)
{
ftpStream.Close();
}
if (response != null)
{
response.Close();
}
}
return outputStream;
}

#endregion

#region 获取当前目录下明细
/// <summary>
/// 获取当前目录下明细(包含文件和文件夹)
/// </summary>
/// <returns></returns>
public static string[] GetFilesDetailList(string remoteFilepath)
{
try
{
StringBuilder result = new StringBuilder();
FtpWebRequest ftp;
ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri(remoteFilepath));
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetFilesDetailList" + ftpURI + "/" + remoteFilepath);
ftp.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
WebResponse response = ftp.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
string line = reader.ReadLine();

while (line != null)
{
result.Append(line);
result.Append(" ");
line = reader.ReadLine();
}
reader.Close();
response.Close();
return result.ToString().TrimEnd(' ').Split(' ');
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetFilesDetailList" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetFilesDetailList" + e.Message.ToString() + e.StackTrace);
return null;
}
}

/// <summary>
/// 获取当前目录下文件列表(仅文件)
/// </summary>
/// <returns></returns>
public static string[] GetFileList(string remoteFilepath)
{
StringBuilder result = new StringBuilder();
FtpWebRequest reqFTP;
try
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(remoteFilepath));
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetFileList" + ftpURI);
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
WebResponse response = reqFTP.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);

string line = reader.ReadLine();
while (line != null)
{
if (remoteFilepath.Trim() != string.Empty && remoteFilepath.Trim() != "*.*")
{
if (remoteFilepath.Contains("*"))
{
string mask_ = remoteFilepath.Substring(0, remoteFilepath.IndexOf("*"));
if (line.Substring(0, mask_.Length) == mask_)
{
result.Append(line);
result.Append(" ");
}
}
else
{
result.Append(line);
result.Append(" ");
}
}
else
{
result.Append(line);
result.Append(" ");
}
line = reader.ReadLine();
}
reader.Close();
response.Close();
return result.ToString().TrimEnd(' ').Split(' ');
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetFileList" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetFileList" + e.Message.ToString() + e.StackTrace);
return null;
}
}

/// <summary>
/// 获取当前目录下所有的文件夹列表(仅文件夹)
/// </summary>
/// <returns></returns>
public static string[] GetDirectoryList(string remoteFilepath)
{
string[] drectory = GetFilesDetailList(remoteFilepath);//获取当前目录下明细
string m = string.Empty;
if (drectory != null)
{
foreach (string str in drectory)
{
if (!string.IsNullOrWhiteSpace(str))
{
int dirPos = str.IndexOf("<DIR>");
if (dirPos > 0)
{
/*判断 Windows 风格*/
m += str.Substring(dirPos + 5).Trim() + " ";
}
else if (str.Trim().Substring(0, 1).ToUpper() == "D")
{
/*判断 Unix 风格*/
string dir = str.Substring(54).Trim();
if (dir != "." && dir != "..")
{
m += dir + " ";
}
}
}
}
}
char[] n = new char[] { ' ' };
return m.TrimEnd(n).Split(n);
}
#endregion

#region 删除文件及文件夹
/// <summary>
/// 删除文件
/// </summary>
/// <param name="fileName"></param>
public static bool Delete(string fileName)
{
try
{
//string uri = ftpURI + fileName;
string uri = fileName;
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("Delete" + uri);
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;

string result = String.Empty;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
long size = response.ContentLength;
Stream datastream = response.GetResponseStream();
StreamReader sr = new StreamReader(datastream);
result = sr.ReadToEnd();
sr.Close();
datastream.Close();
response.Close();
return true;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("Delete" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("Delete" + e.Message.ToString() + e.StackTrace);
return false;
}
}
/// <summary>
/// 删除文件夹
/// </summary>
/// <param name="folderName"></param>
public static void RemoveDirectory(string folderName)
{
try
{
//string uri = ftpURI + folderName;
string uri = folderName;
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("RemoveDirectory" + uri);
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.RemoveDirectory;

string result = String.Empty;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
long size = response.ContentLength;
Stream datastream = response.GetResponseStream();
StreamReader sr = new StreamReader(datastream);
result = sr.ReadToEnd();
sr.Close();
datastream.Close();
response.Close();
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("RemoveDirectory" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("RemoveDirectory" + e.Message.ToString() + e.StackTrace);
}
}
/// <summary>
/// 删除文件夹及里面的文件(当前文件夹里不可包含文件夹)
/// </summary>
/// <param name="folderName"></param>
public static void RemoveFullDirectory(string folderName)
{
var fileList = GetFileList(folderName);
foreach (var file in fileList)
{
if (!string.IsNullOrWhiteSpace(file))
Delete(folderName + "/" + file);
}
if (DirectoryExist(folderName))
RemoveDirectory(folderName);
}
#endregion

#region 重命名、移动、切换目录
/// <summary>
/// 改名
/// </summary>
/// <param name="currentFilename"></param>
/// <param name="newFilename"></param>
public static bool ReName(string currentFilename, string newFilename)
{
FtpWebRequest reqFTP;
try
{
if (!string.IsNullOrWhiteSpace(newFilename) && newFilename.Contains("."))
{
// 按默认规则创建多层文件夹
MakeMultilayerDir(newFilename.Substring(0, newFilename.LastIndexOf('/')));
}
else
{
MakeMultilayerDir(newFilename);
}
//reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI + currentFilename));
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(currentFilename));
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("ReName" + currentFilename);
reqFTP.Method = WebRequestMethods.Ftp.Rename;
reqFTP.RenameTo = newFilename;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();

ftpStream.Close();
response.Close();
return true;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("ReName" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("ReName" + e.Message.ToString() + e.StackTrace);
return false;
}
}

/// <summary>
/// 移动文件
/// </summary>
/// <param name="currentFilename"></param>
/// <param name="newFilename"></param>
public static bool MoveFile(string currentFilename, string newDirectory)
{
try
{
if (ReName(currentFilename, newDirectory))
return true;
else
return false;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("ReName" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("ReName" + e.Message.ToString() + e.StackTrace);
return false;
}
}

/// <summary>
/// 切换当前目录
/// </summary>
/// <param name="DirectoryName"></param>
/// <param name="IsRoot">true 绝对路径 false 相对路径</param>
public static void GotoDirectory(string DirectoryName, bool IsRoot)
{
try
{
if (IsRoot)
{
ftpRemotePath = DirectoryName;
}
else
{
ftpRemotePath += DirectoryName + "/";
}
ftpURI = ftpURI + "/" + ftpRemotePath + "/";
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GotoDirectory" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GotoDirectory" + e.Message.ToString() + e.StackTrace);
}
}
#endregion

#region Stream和byte[]相互转换
/// <summary>
/// Stream 转成 byte[]
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static byte[] StreamToBytes(Stream stream)
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
// 设置当前流的位置为流的开始
stream.Seek(0, SeekOrigin.Begin);
return bytes;
}
/// <summary>
/// byte[] 转成 Stream
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static Stream BytesToStream(byte[] bytes)
{
Stream stream = new MemoryStream(bytes);
return stream;
}
#endregion

#region 复制Stream
public static Stream CopyFile(Stream stream)
{
//每次读取的长度
int eachReadLength = 2048;
//将源文件 读取成文件流
//FileStream stream = new FileStream(fromPath, FileMode.Open, FileAccess.Read);
//已追加的方式 写入文件流
//FileStream toFile = new FileStream(toPath, FileMode.Append, FileAccess.Write);
Stream copyStream = new MemoryStream();
//实际读取的文件长度
int toCopyLength = 0;
//如果每次读取的长度小于 源文件的长度 分段读取
if (eachReadLength < stream.Length)
{
byte[] buffer = new byte[eachReadLength];
long copied = 0;
while (copied <= stream.Length - eachReadLength)
{
toCopyLength = stream.Read(buffer, 0, eachReadLength);
stream.Flush();
copyStream.Write(buffer, 0, eachReadLength);
copyStream.Flush();
//流的当前位置
copyStream.Position = stream.Position;
copied += toCopyLength;

}
int left = (int)(stream.Length - copied);
toCopyLength = stream.Read(buffer, 0, left);
stream.Flush();
copyStream.Write(buffer, 0, left);
copyStream.Flush();

}
else
{
//如果每次拷贝的文件长度大于源文件的长度 则将实际文件长度直接拷贝
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Flush();
copyStream.Write(buffer, 0, buffer.Length);
copyStream.Flush();

}
stream.Close();
copyStream.Close();
return copyStream;
}
#endregion

#region 获取Stream的Md5
/// <summary>
/// 获取MD5文件流
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static string GetStreamMd5(Stream stream)
{
var oMd5Hasher = new MD5CryptoServiceProvider();
byte[] arrbytHashValue = oMd5Hasher.ComputeHash(stream);
//由以连字符分隔的十六进制对构成的String,其中每一对表示value 中对应的元素;例如“F-2C-4A”
string strHashData = BitConverter.ToString(arrbytHashValue);
//替换
strHashData = strHashData.Replace("-", "");
return strHashData;
}
#endregion

#region 合并文件

/// <summary>
/// 合并文件
/// </summary>
/// <param name="fileNames">文件</param>
/// <param name="sourceFileName"></param>
/// <param name="isDelet"></param>
public async static void FileCombine(List<string> fileNames, string sourceFileName, string remoteFilepath, bool isDelet = false)
{
try
{
foreach (var filename in fileNames)
{
Stream blockStream = await FtpAsyncDownload(remoteFilepath + "/" + filename);//从FTP服务器下载文件,指定本地路径和本地文件名
FtpUploadFileOrBroken(blockStream, sourceFileName, remoteFilepath);//上传文件到FTP服务器(单次上传或续传)
if (isDelet)
{
Delete(remoteFilepath + "/" + filename);
}
}
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("FileCombine" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("FileCombine" + e.Message.ToString() + e.StackTrace);
}
}

#endregion

#region 业务相关
/// <summary>
/// 获取Ftp默认规则文件路径
/// </summary>
/// <returns></returns>
public static string GetDefaultPath()
{
try
{
if (!string.IsNullOrWhiteSpace(rootPath))
{
rootPath = rootPath.TrimStart('/').TrimEnd('/');
}
// 没有指定保存文件则默认生成 year/month/day
var remoteFilepath = ftpURI + rootPath + "/" + DateTime.Now.Year.ToString().PadLeft(2, '0')
+ "/" + DateTime.Now.Month.ToString().PadLeft(2, '0')
+ "/" + DateTime.Now.Day.ToString().PadLeft(2, '0');
return remoteFilepath;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetDefaultPath" + e.Message.ToString() + e.StackTrace);
//LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetDefaultPath" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}
/// <summary>
///
/// </summary>
/// <param name="businessTypeName"></param>
/// <returns></returns>
public static string GetFileDefaultPath(string businessTypeName)
{
try
{
// 没有指定保存文件则默认生成 year/month/day
var remoteFilepath = ftpBasePath + businessTypeName
+ "/" + DateTime.Now.Year.ToString().PadLeft(2, '0')
+ "/" + DateTime.Now.Month.ToString().PadLeft(2, '0')
+ "/" + DateTime.Now.Day.ToString().PadLeft(2, '0');
return remoteFilepath;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetFileDefaultPath" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}
/// <summary>
///
/// </summary>
/// <param name="businessTypeName"></param>
/// <returns></returns>
public static string GetDestnationFileDefaultPath(string businessTypeName)
{
try
{
if (!string.IsNullOrWhiteSpace(rootPath))
{
rootPath = rootPath.TrimStart('/').TrimEnd('/');
}
// 没有指定保存文件则默认生成 year/month/day
var remoteFilepath = "/" + rootPath + "/" + businessTypeName
+ "/" + DateTime.Now.Year.ToString().PadLeft(2, '0')
+ "/" + DateTime.Now.Month.ToString().PadLeft(2, '0')
+ "/" + DateTime.Now.Day.ToString().PadLeft(2, '0');
return remoteFilepath;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetFileDefaultPath" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}

/// <summary>
/// 获取PC版本目录文件
/// </summary>
/// <returns></returns>
public static string GetPcVersionPath()
{
try
{
if (!string.IsNullOrWhiteSpace(rootPath))
{
rootPath = rootPath.TrimStart('/').TrimEnd('/');
}
if (!string.IsNullOrWhiteSpace(PcVersionPath))
{
PcVersionPath = PcVersionPath.TrimStart('/').TrimEnd('/');
}
return ftpURI + rootPath + "/" + PcVersionPath;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetPcVersionPath" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetPcVersionPath" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}

/// <summary>
/// 获取PC发布版本目录
/// </summary>
/// <returns></returns>
public static string GetPcPublishPath()
{
try
{
if (!string.IsNullOrWhiteSpace(rootPath))
{
rootPath = rootPath.TrimStart('/').TrimEnd('/');
}
if (!string.IsNullOrWhiteSpace(PcPublishPath))
{
PcPublishPath = PcPublishPath.TrimStart('/').TrimEnd('/');
}
return ftpURI + rootPath + "/" + PcPublishPath;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetPcPublishPath" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetPcPublishPath" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}
/// <summary>
/// PC版历史发布版本
/// </summary>
/// <returns></returns>
public static string GetPcHistoryVersionPath()
{
try
{
if (!string.IsNullOrWhiteSpace(rootPath))
{
rootPath = rootPath.TrimStart('/').TrimEnd('/');
}
return ftpURI + rootPath + "/" + DateTime.Now.Year.ToString().PadLeft(2, '0')
+ DateTime.Now.Month.ToString().PadLeft(2, '0')
+ DateTime.Now.Day.ToString().PadLeft(2, '0');
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetPcHistoryVersionPath" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetPcHistoryVersionPath" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}

/// <summary>
/// 获取Android发布版本目录
/// </summary>
/// <returns></returns>
public static string GetAndroidPublishPath()
{
try
{
if (!string.IsNullOrWhiteSpace(rootPath))
{
rootPath = rootPath.TrimStart('/').TrimEnd('/');
}
if (!string.IsNullOrWhiteSpace(AndroidPublishPath))
{
AndroidPublishPath = AndroidPublishPath.TrimStart('/').TrimEnd('/');
}
return ftpURI + rootPath + "/" + AndroidPublishPath;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetAndroidPublishPath" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetAndroidPublishPath" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}

/// <summary>
/// 获取iOS发布版本目录
/// </summary>
/// <returns></returns>
public static string GetiOSPublishPath()
{
try
{
if (!string.IsNullOrWhiteSpace(rootPath))
{
rootPath = rootPath.TrimStart('/').TrimEnd('/');
}
if (!string.IsNullOrWhiteSpace(iOSPublishPath))
{
iOSPublishPath = iOSPublishPath.TrimStart('/').TrimEnd('/');
}
return ftpURI + rootPath + "/" + iOSPublishPath;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetiOSPublishPath" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetiOSPublishPath" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}

/// <summary>
/// 获取iOS版本目录文件
/// </summary>
/// <returns></returns>
public static string GetiOSVersionPath()
{
try
{
if (!string.IsNullOrWhiteSpace(rootPath))
{
rootPath = rootPath.TrimStart('/').TrimEnd('/');
}
if (!string.IsNullOrWhiteSpace(iOSVersionPath))
{
iOSVersionPath = iOSVersionPath.TrimStart('/').TrimEnd('/');
}
return ftpURI + rootPath + "/" + iOSVersionPath;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetiOSVersionPath" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetiOSVersionPath" + e.Message.ToString() + e.StackTrace);
return string.Empty;
}
}
#endregion


#region 下载整个文件夹

/// <summary>
/// 从FTP下载整个文件夹
/// </summary>
/// <param name="ftpDir">FTP文件夹路径</param>
/// <param name="saveDir">保存的本地文件夹路径</param>
public static void DownFtpDir(string ftpDir, string saveDir)
{
try
{
List<FileStruct> files = ListFilesAndDirectories(ftpDir);
if (!Directory.Exists(saveDir))
{
Directory.CreateDirectory(saveDir);
}
foreach (FileStruct f in files)
{
if (f.IsDirectory) //文件夹,递归查询
{
DownFtpDir(ftpDir + "/" + f.Name, saveDir + "\" + f.Name);
}
else //文件,直接下载
{
DownLoadFile(ftpDir + "/" + f.Name, saveDir + "\" + f.Name);
}
}
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("DownFtpDir" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("DownFtpDir" + e.Message.ToString() + e.StackTrace);
}
}

#endregion

/// <summary>
/// 列出FTP服务器上面当前目录的所有文件和目录
/// </summary>
/// <param name="ftpUri">FTP目录</param>
/// <returns></returns>
public static List<FileStruct> ListFilesAndDirectories(string ftpUri)
{
WebResponse webresp = null;
StreamReader ftpFileListReader = null;
FtpWebRequest ftpRequest = null;
try
{
ftpRequest = (FtpWebRequest)WebRequest.Create(new Uri(ftpUri));
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
ftpRequest.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
webresp = ftpRequest.GetResponse();
ftpFileListReader = new StreamReader(webresp.GetResponseStream(), Encoding.Default);
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("ListFilesAndDirectories" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("ListFilesAndDirectories" + e.Message.ToString() + e.StackTrace);
}
string Datastring = ftpFileListReader.ReadToEnd();
return GetList(Datastring);

}

/// <summary>
/// 从ftp下载文件到本地服务器
/// </summary>
/// <param name="downloadUrl">要下载的ftp文件路径,如ftp://192.168.1.104/capture-2.avi</param>
/// <param name="saveFileUrl">本地保存文件的路径,如(@"d:capture-22.avi"</param>
public static void DownLoadFile(string downloadUrl, string saveFileUrl)
{
Stream responseStream = null;
FileStream fileStream = null;
StreamReader reader = null;

try
{
FtpWebRequest downloadRequest = (FtpWebRequest)WebRequest.Create(downloadUrl);
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
downloadRequest.Credentials = new NetworkCredential(FtpUserID, FtpPassword);

FtpWebResponse downloadResponse = (FtpWebResponse)downloadRequest.GetResponse();
responseStream = downloadResponse.GetResponseStream();

fileStream = File.Create(saveFileUrl);
byte[] buffer = new byte[1024];
int bytesRead;
while (true)
{
bytesRead = responseStream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
fileStream.Write(buffer, 0, bytesRead);
}
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("DownLoadFile" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("DownLoadFile" + e.Message.ToString() + e.StackTrace);
}
finally
{
if (reader != null)
{
reader.Close();
}
if (responseStream != null)
{
responseStream.Close();
}
if (fileStream != null)
{
fileStream.Close();
}
}
}

/// <summary>
/// 获得文件和目录列表
/// </summary>
/// <param name="datastring">FTP返回的列表字符信息</param>
private static List<FileStruct> GetList(string datastring)
{
List<FileStruct> myListArray = new List<FileStruct>();
try
{
string[] dataRecords = datastring.Split(' ');
FileListStyle _directoryListStyle = GuessFileListStyle(dataRecords);
foreach (string s in dataRecords)
{
if (_directoryListStyle != FileListStyle.Unknown && s != "")
{
FileStruct f = new FileStruct();
f.Name = "..";
switch (_directoryListStyle)
{
case FileListStyle.UnixStyle:
f = ParseFileStructFromUnixStyleRecord(s);
break;
case FileListStyle.WindowsStyle:
f = ParseFileStructFromWindowsStyleRecord(s);
break;
}
if (!(f.Name == "." || f.Name == ".."))
{
myListArray.Add(f);
}
}
}
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GetList" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GetList" + e.Message.ToString() + e.StackTrace);
}
return myListArray;
}

/// <summary>
/// 判断文件列表的方式Window方式还是Unix方式
/// </summary>
/// <param name="recordList">文件信息列表</param>
private static FileListStyle GuessFileListStyle(string[] recordList)
{
try
{
foreach (string s in recordList)
{
if (s.Length > 10
&& Regex.IsMatch(s.Substring(0, 10), "(-|d)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)"))
{
return FileListStyle.UnixStyle;
}
else if (s.Length > 8
&& Regex.IsMatch(s.Substring(0, 8), "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]"))
{
return FileListStyle.WindowsStyle;
}
}
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("GuessFileListStyle" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("GuessFileListStyle" + e.Message.ToString() + e.StackTrace);
}
return FileListStyle.Unknown;
}

/// <summary>
/// 从Unix格式中返回文件信息
/// </summary>
/// <param name="Record">文件信息</param>
private static FileStruct ParseFileStructFromUnixStyleRecord(string Record)
{
FileStruct f = new FileStruct();
try
{
string processstr = Record.Trim();
f.Flags = processstr.Substring(0, 10);
f.IsDirectory = (f.Flags[0] == 'd');
processstr = (processstr.Substring(11)).Trim();
_cutSubstringFromStringWithTrim(ref processstr, ' ', 0); //跳过一部分
f.Owner = _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
f.Group = _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
_cutSubstringFromStringWithTrim(ref processstr, ' ', 0); //跳过一部分
string yearOrTime = processstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[2];
if (yearOrTime.IndexOf(":") >= 0) //time
{
processstr = processstr.Replace(yearOrTime, DateTime.Now.Year.ToString());
}
f.CreateTime = DateTime.Parse(_cutSubstringFromStringWithTrim(ref processstr, ' ', 8));
f.Name = processstr; //最后就是名称
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("ParseFileStructFromUnixStyleRecord" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("ParseFileStructFromUnixStyleRecord" + e.Message.ToString() + e.StackTrace);
}
return f;
}

/// <summary>
/// 从Windows格式中返回文件信息
/// </summary>
/// <param name="Record">文件信息</param>
private static FileStruct ParseFileStructFromWindowsStyleRecord(string Record)
{
FileStruct f = new FileStruct();
try
{
string processstr = Record.Trim();
string dateStr = processstr.Substring(0, 8);
processstr = (processstr.Substring(8, processstr.Length - 8)).Trim();
string timeStr = processstr.Substring(0, 7);
processstr = (processstr.Substring(7, processstr.Length - 7)).Trim();
DateTimeFormatInfo myDTFI = new CultureInfo("en-US", false).DateTimeFormat;
myDTFI.ShortTimePattern = "t";
f.CreateTime = DateTime.Parse(dateStr + " " + timeStr, myDTFI);
if (processstr.Substring(0, 5) == "<DIR>")
{
f.IsDirectory = true;
processstr = (processstr.Substring(5, processstr.Length - 5)).Trim();
}
else
{
string[] strs = processstr.Split(new char[] { ' ' }, 2);// StringSplitOptions.RemoveEmptyEntries); // true);
processstr = strs[1];
f.IsDirectory = false;
}
f.Name = processstr;
}
catch (Exception e)
{
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Error("ParseFileStructFromWindowsStyleRecord" + e.Message.ToString() + e.StackTrace);
LogHelper.GetLog(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName).Info("ParseFileStructFromWindowsStyleRecord" + e.Message.ToString() + e.StackTrace);
}
return f;
}

/// <summary>
/// 按照一定的规则进行字符串截取
/// </summary>
/// <param name="s">截取的字符串</param>
/// <param name="c">查找的字符</param>
/// <param name="startIndex">查找的位置</param>
private static string _cutSubstringFromStringWithTrim(ref string s, char c, int startIndex)
{
int pos1 = s.IndexOf(c, startIndex);
string retString = s.Substring(0, pos1);
s = (s.Substring(pos1)).Trim();
return retString;
}
}

#region 文件信息结构
public struct FileStruct
{
public string Flags;
public string Owner;
public string Group;
public bool IsDirectory;
public DateTime CreateTime;
public string Name;
}
public enum FileListStyle
{
UnixStyle,
WindowsStyle,
Unknown
}
#endregion
}

原文地址:https://www.cnblogs.com/Nine4Cool/p/10540631.html