C# 实现 微软WebRequestMethods.Ftp类中的FTP操作功能
先奉献一个测试地址,ftp内的文件请勿删除,谢谢
FtpEntity fe = new FtpEntity("wjshan0808.3vhost.net", "wjshan0808", "");
由于代码量较多,只抽出一部分,详细代码请移步 ftp://wjshan0808.3vhost.net/FtpEntity/或 随笔后面有源码下载地址
部分字段
#region fields
private const string PATTERN = @"^([dlb-])([rwx-]{9})\s+(\d{1,})\s+(\w+)\s+(.+?\b)\s+(\d{1,})\s+(.+?)\s+(\d{1,2})\s+(\d{2}:?\d{2})\s+(.+)$";
private const int DYNAMICINCREASEVALUE = * ;//512KB
private const int DYNAMICIMCEPTVALUE = * ;//64KB;
private static ReaderWriterLock _lok = new ReaderWriterLock();
private int _dynamicBufferSize = ;
private bool _isDownloadCheck = true;
private bool _isUploadCheck = false;
private Dictionary<Uri, long> _dicFileSize = null;
private int _sendBufferSize = * ;//128KB
#endregion
#region props
/// <summary>
/// 当文件数据上传完成时发生
/// </summary>
public event UploadCompletedEventHandler UploadCompleted;
/// <summary>
/// 获取或设置上传数据的缓冲区大小
/// </summary>
public int SendBufferSize
{
get { return _sendBufferSize; }
set
{
if (value < )
value = * ;
_lok.AcquireWriterLock();
try
{
_sendBufferSize = value;
}
finally
{
_lok.ReleaseWriterLock();
}
}
}
/// <summary>
/// 获取请求FTP服务器的协议地址
/// </summary>
public string Address
{
get { return string.Format("ftp://{0}:{1}", _address, Port); }
}
/// <summary>
/// 获取或设置相对FTP根目录的绝对路径,默认为Ftp根目录
/// </summary>
public string AbsolutePath
{
get { return _absolutePath; }
set
{
IsNull(ref value);
while (value.StartsWith("/"))
{
value = value.TrimStart('/');
}
if (value.IndexOfAny(Path.GetInvalidPathChars()) >= )
throw new ArgumentException("RelativeUrl:Invalid Value");
_absolutePath = value;
}
}
/// <summary>
/// 获取请求FTP服务器的解析地址
/// </summary>
public string ResolveUrl
{
get { return Path.Combine(Address, AbsolutePath).Replace(@"\", "/"); }
}
#endregion
1.获取详细列表
/// <summary>
/// 获取 AbsolutePath (属性值)下的文件(夹)的详细列表
/// </summary>
/// <param name="total">总用量</param>
/// <param name="absolutePath">目标地址</param>
/// <returns>文件(夹)详细信息</returns>
public FtpDirectoryDetails[] ListDirectoryDetails(out int total, string absolutePath = null)
{
if (absolutePath != null && absolutePath != string.Empty)
AbsolutePath = absolutePath;
using (FtpWebResponse response = SyncInternalCommon(WebRequestMethods.Ftp.ListDirectoryDetails))
{
total = ;
IList<FtpDirectoryDetails> fddes = new List<FtpDirectoryDetails>();
StreamReader reader = null;
try
{
if (response.StatusCode == FtpStatusCode.OpeningData)
{
reader = new StreamReader(response.GetResponseStream(), Encoding.Default, true);
}
if (reader == null) throw new ArgumentNullException("reader");
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
MatchCollection mc = Regex.Matches(line, PATTERN, RegexOptions.CultureInvariant);
if (mc.Count == )
{
object[] tmp = new object[];
mc[].Groups.CopyTo(tmp, );
fddes.Add(new FtpDirectoryDetails(tmp));
}
else //total
{
total = int.Parse(Regex.Match(line, @"\d{1,}", RegexOptions.CultureInvariant).Value);
}
}
return fddes.ToArray();
}
catch (Exception ex)
{
Log(ex);
throw ex;
}
finally
{
if (reader != null)
reader.Close();
}
}
}
目录详细信息类
/// <summary>
/// 目录文件信息
/// </summary>
public struct FtpDirectoryDetails
{
public FtpDirectoryType Type { get; set; }
public FtpDirectoryAccess[] Access { get; set; }
public short Count { get; set; }
public string User { get; set; }
public string Group { get; set; }
public long Size { get; set; }
public DateTime LastModified { get; set; }
//public string Year { get; set; }
public string Name { get; set; } public FtpDirectoryDetails(object[] details)
{
Type = FtpDirectoryType.Unknow;
Access = new FtpDirectoryAccess[] { FtpDirectoryAccess.None, FtpDirectoryAccess.None, FtpDirectoryAccess.None }; Count = short.Parse(details[].ToString());
User = details[].ToString();
Group = details[].ToString(); Size = long.Parse(details[].ToString()); LastModified = DateTime.MinValue; Name = details[].ToString();
//
SetType(details[].ToString());
SetAccess(details[].ToString());
SetLastModified(details[].ToString(), details[].ToString(), details[].ToString());
} private void SetLastModified(string month, string day, string time0year)
{
StringBuilder sb = new StringBuilder();
bool contains = time0year.Contains(":");
sb.Append(contains ? DateTime.Now.Year.ToString() : time0year);
sb.Append(" ");
sb.Append(string.Format("{0:00}", SetMonth(month)));
sb.Append(" ");
sb.Append(string.Format("{0:00}", day));
sb.Append(" ");
sb.Append(contains ? time0year : "00:00");
sb.Append(":00");
LastModified = DateTime.Parse(sb.ToString());
} /// <summary>
/// 1.英文
/// 2.阿拉伯数字
/// 3.两位阿拉伯数字
/// 4.(2,3)+中文
/// </summary>
/// <param name="month"></param>
/// <returns></returns>
private object SetMonth(string month)
{
if (month[month.Length - ] <= )//最后一位是数字
return month; if (month[] <= )//第一位是数字
return month.Substring(, month.Length - ); if ("January".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Jan
return ;
else if ("February".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Feb
return ;
else if ("March".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Mar
return ;
else if ("April".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Apr
return ;
else if ("May".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//May
return ;
else if ("June".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Jun
return ;
else if ("July".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Jul
return ;
else if ("August".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Aug
return ;
else if ("September".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Sep
return ;
else if ("October".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Oct
return ;
else if ("November".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Nov
return ;
else
//("December".StartsWith(month, StringComparison.CurrentCultureIgnoreCase))//Dec
return ;
} private void SetAccess(string access)
{
for (int i = ; i < access.Length; i += )
{
FtpDirectoryAccess acc = FtpDirectoryAccess.None;
for (int j = i; j < (i + ); j++)
{
switch (access[j])
{
case 'r':
acc |= FtpDirectoryAccess.Read;
break;
case 'w':
acc |= FtpDirectoryAccess.Write;
break;
case 'x':
acc |= FtpDirectoryAccess.Execute;
break;
default:// '-':
acc |= FtpDirectoryAccess.None;
break;
}
}
Access[i / ] = acc;
}
}
private void SetType(string type)
{
switch (type)
{
case "d":
Type = FtpDirectoryType.Folder;
break;
case "-":
Type = FtpDirectoryType.File;
break;
case "l":
Type = FtpDirectoryType.Link;
break;
case "b":
Type = FtpDirectoryType.Block;
break;
default:
Type = FtpDirectoryType.Unknow;
break;
}
}
}
2.上传
#region UploadCommon
protected void SyncUploadCommon(string file, bool withUnique = false, long offset = )
{
CheckUrl(file, withUnique);
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
if (offset > )
fs.Seek(offset, SeekOrigin.Begin);
FtpWebRequest request = WebRequest.Create(ResolveUrl) as FtpWebRequest;
request.Credentials = Credential;
request.UsePassive = false;
request.ContentLength = fs.Length;
if (withUnique && offset == )
request.Method = WebRequestMethods.Ftp.UploadFileWithUniqueName;
else
request.Method = offset > ? WebRequestMethods.Ftp.AppendFile : WebRequestMethods.Ftp.UploadFile;
string path = request.RequestUri.AbsolutePath;
Stream stream = null;
BinaryReader reader = null;
FtpTransmissionStatus status = FtpTransmissionStatus.Ok;
try
{
stream = request.GetRequestStream();
if (stream == null)
throw new ArgumentNullException("stream");
reader = new BinaryReader(fs, Encoding.Default);
if (reader == null)
throw new ArgumentNullException("reader");
while (reader.PeekChar() != -)
{
byte[] bt = reader.ReadBytes(_sendBufferSize);
stream.Write(bt, , bt.Length);
stream.Flush();
}
//GetResponse after Close }
catch (Exception ex)
{
status = FtpTransmissionStatus.Error;
Log(ex);
//throw ex;
}
finally
{
if (reader != null)
reader.Close();
if (stream != null)
stream.Close(); if (UploadCompleted != null)
{
Thread.Sleep();
UploadCompleted(new object(),
new UploadCompletedEventArgs()
{
Length = (!withUnique && IsUploadCheck) ? GetFileSize(path) : -,//异步时文件路径会改变
Path = path,
FileName = (!withUnique) ? Path.GetFileName(path) : string.Empty,
UploadStatus = status
});
}
}
}
protected void AsyncUploadCommon(string file, long offset = , bool withUnique = false)
{
CheckUrl(file, withUnique);
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
if (offset > )
fs.Seek(offset, SeekOrigin.Begin);
FtpWebRequest request = WebRequest.Create(ResolveUrl) as FtpWebRequest;
request.Credentials = Credential;
request.UsePassive = false;
request.ContentLength = fs.Length;
if (withUnique && offset == )
request.Method = WebRequestMethods.Ftp.UploadFileWithUniqueName;
else
request.Method = offset > ? WebRequestMethods.Ftp.AppendFile : WebRequestMethods.Ftp.UploadFile; FtpState state = new FtpState() { Request = request, FileStream = fs, Path = request.RequestUri.AbsolutePath, Unique = withUnique };
try
{
IAsyncResult iar = request.BeginGetRequestStream(new AsyncCallback(UploadCallBack), state);
}
catch (Exception ex)
{
Log(ex);
state.Dispose();
//throw ex;
}
}
protected void UploadCallBack(IAsyncResult ar)
{
FtpState state = ar.AsyncState as FtpState;
if (state == null) throw new ArgumentNullException("state");
if (state.Request == null) throw new ArgumentNullException("state.Request");
if (state.FileStream == null) throw new ArgumentNullException("state.FileStream");
FtpTransmissionStatus status = FtpTransmissionStatus.Ok;
try
{
if (ar.IsCompleted)
{
Stream stream = state.Request.EndGetRequestStream(ar);
if (stream == null)
throw new ArgumentNullException("stream");
state.Stream = stream;
}
while (IsReadToEnd)
{
byte[] bt = new byte[SendBufferSize];
int length = state.FileStream.Read(bt, , bt.Length);
if (length == ) break;
IAsyncResult iar = state.Stream.BeginWrite(bt, , length, null, null);
state.Stream.EndWrite(iar);
state.Stream.Flush();
}
//GetResponse after Close }
catch (Exception ex)
{
status = FtpTransmissionStatus.Error;
Log(ex);
//throw ex;
}
finally
{
string path = state.Path;
bool withUnique = state.Unique;
state.Dispose(); if (UploadCompleted != null)
{
Thread.Sleep();
UploadCompleted(new object(),
new UploadCompletedEventArgs()
{
Length = (!withUnique && IsUploadCheck) ? GetFileSize(path) : -,//异步时文件路径会改变
Path = path,
FileName = (!withUnique) ? Path.GetFileName(path) : string.Empty,
UploadStatus = status
});
}
}
}
#endregion
辅助函数
private int DynamicBufferSize(int length)
{
if (length == )
length += DYNAMICIMCEPTVALUE;
if (length == _dynamicBufferSize)
length += DYNAMICINCREASEVALUE;
length += -_dynamicBufferSize;
if ((length + _dynamicBufferSize) <= )
length += DYNAMICIMCEPTVALUE;
return Interlocked.Add(ref _dynamicBufferSize, length);
}
private void CheckPath(string path)
{
if (path == null)
throw new ArgumentNullException(path);
if (path.IndexOfAny(Path.GetInvalidPathChars()) >= )
throw new ArgumentException("Invalid Path");
if (!File.Exists(path))
throw new FileNotFoundException();
}
private string CheckName(string value)
{
if (value == null || value == string.Empty)
throw new ArgumentNullException(value);
if (value.IndexOfAny(Path.GetInvalidFileNameChars()) >= )
throw new WarningException(value + "Invalid FileName");
return value;
}
private void CheckUrl(string file, bool withUnique)
{
string name = Path.GetFileName(file);
string uploadname = Path.GetFileName(AbsolutePath);
if (uploadname == string.Empty)
{
AbsolutePath = AbsolutePath.TrimEnd(new char[] { '/' }) + "/" + name;
}
}
private void IsNull(ref string value)
{
if (value != null) return;
value = string.Empty;
}
测试代码
private void btnTest_Click(object sender, EventArgs e)
{
fe.UploadCompleted += new UploadCompletedEventHandler(Fe_UploadCompleted);
try
{
fe.AbsolutePath = "FtpEntity";
Files(@"C:\Users\Administrator\Desktop\FtpEntity\FtpEntity");
}
catch (Exception ex)
{
}
}
public void Files(string dir)
{
DirectoryInfo di = new DirectoryInfo(dir);
foreach (DirectoryInfo item in di.GetDirectories())
{
string tmp1 = fe.AbsolutePath;
fe.AbsolutePath += "/" + item.Name;
fe.MakeDirectory();
Files(item.FullName);
fe.AbsolutePath = tmp1;
}
foreach (FileInfo fi in di.GetFiles())
{
string tmp2 = fe.AbsolutePath;
fe.AbsolutePath += "/" + fi.Name;
fe.AsyncUploadFile(fi.FullName);
fe.AbsolutePath = tmp2;
}
}
private void Fe_UploadCompleted(object sender, UploadCompletedEventArgs e)
{
if (rtxtLog.InvokeRequired)
{
rtxtLog.Invoke(new UploadCompletedEventHandler(Fe_UploadCompleted), new object[] { sender, e });
}
else
{
rtxtLog.Text += Environment.NewLine + "-----------";
rtxtLog.Text += e.Length + Environment.NewLine
+ e.FileName + Environment.NewLine
+ e.FileSize + Environment.NewLine
+ e.Path + Environment.NewLine
+ e.UploadStatus;
rtxtLog.Text += Environment.NewLine + "-----------";
}
}
源文件地址 http://pan.baidu.com/s/1o6rLR2y
C# 实现 微软WebRequestMethods.Ftp类中的FTP操作功能的更多相关文章
- String类中常用的操作
一.获取: 1.获取字符串的长度(注意是方法,不是跟数组的属性一样的) int length(); 1 public static void getLength(){ 2 String s = &qu ...
- JAVA实现File类中的遍历操作并输出内容
package shb.java.testIo; import java.io.BufferedReader; import java.io.BufferedWriter; import java.i ...
- VC++ 在类中添加多线程操作
CTestThread.h public: CTestThread(void); ~CTestThread(void); public: void setvalue(); static DWORD _ ...
- 解析C#类中的构造函数
<解析C#类中的构造函数> 一. C#中的构造函数概述: C#中类包含数据成员和函数成员.函数成员提供了操作类中数据的某些功能,包括方法.属性.构造器和终结器.运算符和索引器. 构造函数 ...
- JavaScript中使用ActiveXObject操作本地文件夹的方法
转载地址 http://www.jb51.net/article/48538.htm 在Windows平台上, js可以调用很多Windows提供的ActivexObject,本文就使用js来实 ...
- Python中的切片操作
python中的切片操作功能十分强大,通常我们利用切片来进行提取信息,进行相关的操作,下面就是一些切片的列子. 列如我们从range函数1-100中取7的倍数,函数及结果如下所示: >>& ...
- java高并发系列 - 第21天:java中的CAS操作,java并发的基石
这是java高并发系列第21篇文章. 本文主要内容 从网站计数器实现中一步步引出CAS操作 介绍java中的CAS及CAS可能存在的问题 悲观锁和乐观锁的一些介绍及数据库乐观锁的一个常见示例 使用ja ...
- 一个封装比较完整的FTP类——clsFTP
前几天,看见园子里面的博友写了一个支持断点续传的FTP类,一时技痒,干脆写了个更完整的clsFtp类.只是我写这个clsFtp不是支持断点续传的目的,而是为了封装FTP几个基本常用的操作接口. 功能 ...
- 在Window的IIS中创建FTP的Site并用C#进行文件的上传下载
文件传输协议 (FTP) 是一个标准协议,可用来通过 Internet 将文件从一台计算机移到另一台计算机. 这些文件存储在运行 FTP 服务器软件的服务器计算机上. 然后,远程计算机可以使用 FTP ...
随机推荐
- AJAX-跨域解决之 JSONP
(一)AJAX ajax 就是从某个文件中去找相关的数据,把数据拿过来以后,利用数据 分析数据 去做我们想做的事情 分两部分:拿数据 用数据 oUsername ...
- posix and system V IPC
轉載自 http://www1.huachu.com.cn/read/readbook.asp?bookid=10104131 http://www1.huachu.com.cn/read/readb ...
- Emmet:HTML/CSS代码快速编写神器
本文来源:http://www.iteye.com/news/27580 ,还可参考:http://www.w3cplus.com/tools/emmet-cheat-sheet.html Em ...
- Oracle数据库合并行记录,WMSYS.WM_CONCAT 函數的用法
Sql代码 select t.rank, t.Name from t_menu_item t; 10 CLARK 10 KING 10 MILLER 20 ADAMS 20 F ...
- ZeroclipboardJS+flash实现将内容复制到剪贴板实例
Zeroclipboard 的实现原理 Zeroclipboard 利用 Flash 进行复制,之前有 Clipboard Copy 解决方案,其利用的是一个隐藏的 Flash.但最新的 Flash ...
- VMwareTools 安装(VMware Player)
1. VMare Tools 按钮是灰化的,需要对虚拟机做如下设置:(在虚拟机没有启动的状态下进行) 1)Player(P)->管理->虚拟机设置->CD/DVD 选择:使 ...
- Hibernate常用增删改查方法
/** * @param obj * @return * 添加数据 */ public Serializable saveObject(Object obj){ return this.getHibe ...
- 第1章 JavaScript概述
学习要点:1.什么是JavaScript2.JavaScript特点3.JavaScript历史4.JavaScript核心5.开发工具集 JavaScript诞生于1995年.它当时的目的是为了验证 ...
- border-radius
- HDU1063 大数 java
Exponentiation Time Limit: 2000/500 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...