csharp: FTP Client Library using System.Net.FtpClient and FluentFTP,测试中存在的BUG修正

https://netftp.codeplex.com/

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/// <summary>
 /// Gets a file listing from the server. Each FtpListItem object returned
 /// contains information about the file that was able to be retrieved. If
 /// a DateTime property is equal to DateTime.MinValue then it means the
 /// date in question was not able to be retrieved. If the Size property
 /// is equal to 0 then it means the size of the object could also not
 /// be retrieved.
 /// 读取文件或文件夹
 /// </summary>
 /// <param name="path">The path of the directory to list</param>
 /// <param name="options">Options that dictacte how a list is performed and what information is gathered.根据选项读取文件或文件夹或其文件的属性</param>
 /// <returns>An array of FtpListItem objects</returns>
 /// <example><code source="..\Examples\GetListing.cs" lang="cs" /></example>
 public FtpListItem[] GetListing(string path, FtpListOption options) {
     FtpListItem item = null;
     List<FtpListItem> lst = new List<FtpListItem>();
     List<string> rawlisting = new List<string>();
     string listcmd = null;
     string pwd = GetWorkingDirectory();
     string buf = null;
 
     if (path == null || path.Trim().Length == 0) {
         pwd = GetWorkingDirectory();
         if (pwd != null && pwd.Trim().Length > 0)
             path = pwd;
         else
             path = "./";
     }
     else if (!path.StartsWith("/") && pwd != null && pwd.Trim().Length > 0) {
         if (path.StartsWith("./"))
             path = path.Remove(0, 2);
         path = string.Format("{0}/{1}", pwd, path).GetFtpPath();
     }
 
     // MLSD provides a machine parsable format with more
     // accurate information than most of the UNIX long list
     // formats which translates to more effcient file listings
     // so always prefer MLSD over LIST unless the caller of this
     // method overrides it with the ForceList option
     // !=
     if ((options & FtpListOption.ForceList) == FtpListOption.ForceList && HasFeature(FtpCapability.MLSD))
     {
         listcmd = "MLSD";
     }
     else
     {
         if ((options & FtpListOption.UseLS) == FtpListOption.UseLS)
         {
             listcmd = "LS";
         }
         else if ((options & FtpListOption.NameList) == FtpListOption.NameList)
         {
             listcmd = "NLST"; //读取文件名
         }
         else
         {
             string listopts = "";
             listcmd = "LIST"; //读取所有文件夹文件
             if ((options & FtpListOption.AllFiles) == FtpListOption.AllFiles)
                 listopts += "a";
 
             if ((options & FtpListOption.Recursive) == FtpListOption.Recursive)
                 listopts += "R";
 
             if (listopts.Length > 0)
                 listcmd += " -" + listopts;
         }
     }
 
     if((options & FtpListOption.NoPath) != FtpListOption.NoPath)
     {
         listcmd = string.Format("{0} {1}", listcmd, path.GetFtpPath());
     }
 
     lock (m_lock)
     {
         Execute("TYPE I");
         //NLST /htdocs 读文件
         // read in raw file listing     MLSD /htdocs
         using (FtpDataStream stream = OpenDataStream(listcmd, 0)) {
             try {
                 while ((buf = stream.ReadLine(Encoding)) != null) {
                     if (buf.Length > 0)
                     {
                         rawlisting.Add(buf);
                         FtpTrace.WriteLine(buf);
                     }
                     //rawlisting.Add(buf);
                     //FtpTrace.WriteLine(buf);
                 }
             }
             finally {
                 stream.Close();
             }
         }
     }
 
 
     //根据上一个循环来读文件或文件夹的属性
     for (int i = 0; i < rawlisting.Count; i++) {
         buf = rawlisting[i];
         if ((options & FtpListOption.NameList) == FtpListOption.NameList) {
             // if NLST was used we only have a file name so
             // there is nothing to parse.
             item = new FtpListItem() {
                 FullName = buf
             };
 
             if (DirectoryExists(item.FullName))
                 item.Type = FtpFileSystemObjectType.Directory;
             else
                 item.Type = FtpFileSystemObjectType.File;
 
             lst.Add(item);
         }
         else {
             // if this is a result of LIST -R then the path will be spit out
             // before each block of objects
             if (listcmd.StartsWith("LIST") && (options & FtpListOption.Recursive) == FtpListOption.Recursive) {
                 if (buf.StartsWith("/") && buf.EndsWith(":")) {
                     path = buf.TrimEnd(':');
                     continue;
                 }
             }
 
             // if the next line in the listing starts with spaces
             // it is assumed to be a continuation of the current line
             if (i + 1 < rawlisting.Count && (rawlisting[i + 1].StartsWith("\t") || rawlisting[i + 1].StartsWith(" ")))
                 buf += rawlisting[++i];
 
             item = FtpListItem.Parse(path, buf, m_caps); //重复了文件夹名称
             // FtpListItem.Parse() returns null if the line
             // could not be parsed
             if (item != null && (item.Name != "." && item.Name != ".."))
                 lst.Add(item);
             else
                 FtpTrace.WriteLine("Failed to parse file listing: " + buf);
         }
 
         // load extended information that wasn't available if the list options flags say to do so.
         if (item != null) {
             // try to dereference symbolic links if the appropriate list
             // option was passed
             if (item.Type == FtpFileSystemObjectType.Link && (options & FtpListOption.DerefLinks) == FtpListOption.DerefLinks) {
                 item.LinkObject = DereferenceLink(item);
             }
 
             if ((options & FtpListOption.Modify) == FtpListOption.Modify && HasFeature(FtpCapability.MDTM)) {
                 // if the modified date was not loaded or the modified date is more than a day in the future
                 // and the server supports the MDTM command, load the modified date.
                 // most servers do not support retrieving the modified date
                 // of a directory but we try any way.
                 if (item.Modified == DateTime.MinValue || listcmd.StartsWith("LIST")) {
                     DateTime modify;
 
                     if (item.Type == FtpFileSystemObjectType.Directory)
                         FtpTrace.WriteLine("Trying to retrieve modification time of a directory, some servers don't like this...");
 
                     if ((modify = GetModifiedTime(item.FullName)) != DateTime.MinValue)
                         item.Modified = modify;
                 }
             }
 
             if ((options & FtpListOption.Size) == FtpListOption.Size && HasFeature(FtpCapability.SIZE)) {
                 // if no size was parsed, the object is a file and the server
                 // supports the SIZE command, then load the file size
                 if (item.Size == -1) {
                     if (item.Type != FtpFileSystemObjectType.Directory) {
                         item.Size = GetFileSize(item.FullName);
                     }
                     else {
                         item.Size = 0;
                     }
                 }
             }
         }
     }
 
     return lst.ToArray();
 }
 
/// <summary>
 /// Creates a valid FTP path by appending the specified segments to this string
 /// </summary>
 /// <param name="path">This string</param>
 /// <param name="segments">The path segments to append</param>
 /// <returns>A valid FTP path</returns>
 public static string GetFtpPath(this string path, params string[] segments) {
     if (String.IsNullOrEmpty(path))
         path = "./";
 
     foreach (string part in segments) {
         if (part != null) {
             if (path.Length > 0 && !path.EndsWith("/"))
                 path += "/";
             //path += Regex.Replace(part.Replace('\\', '/'), "[/]+", "/").TrimEnd('/'); //变成重复
         }
     }
 
     path = Regex.Replace(path.Replace('\\', '/'), "[/]+", "/").TrimEnd('/');
     if (path.Length == 0)
         path = "/";
 
     /*if (!path.StartsWith("/") || !path.StartsWith("./"))
         path = "./" + path;*/
 
     return path;
 }

  测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
   /// <summary>
    /// 涂聚文
    /// Geovin Du
    /// 2017-08-02
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button1_Click(object sender, EventArgs e)
    {
        FtpClient client = new FtpClient();
        client.Host = ftpServer;
        client.Encoding = System.Text.Encoding.GetEncoding("GB2312");
        // if you don't specify login credentials, we use the "anonymous" user account
        client.Credentials = new NetworkCredential(user, pwd);
 
        // begin connecting to the server
        client.Connect();
        //client.SetWorkingDirectory("/htdocs/");
 
        //文件夹和文件(未成功)
        //FtpListOption.NameList 当前文件夹下的文件
        //FtpListOption.AllFiles 当前文件夹下文件和文件夹
        FtpListItem[] items = client.GetListing("/htdocs/", FtpListOption.AllFiles);//根目录下可以。 AllFiles
        this.dataGridView1.DataSource = items;
 
        //获取的是所有文件名
        //client.SetWorkingDirectory("/htdocs/");
        //string[] items = client.GetNameListing();
        //List<FileInfoList> list = new List<FileInfoList>();
        //foreach (string str in items)
        //{
        //    FileInfoList info = new FileInfoList();
        //    info.Name = str;
        //    info.Date = DateTime.Now;
        //    list.Add(info);
        //}
        //this.dataGridView1.DataSource = list;
    }
}
 
/// <summary>
///
/// </summary>
public class FileInfoList
{
    public string Name { set; get; }
 
    public DateTime Date { set; get; }
 
}

 https://github.com/hgupta9/FluentFTP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
        /// <summary>
        /// Gets a file listing from the server. Each <see cref="FtpListItem"/> object returned
        /// contains information about the file that was able to be retrieved.
        /// 读取文件和文件夹
        /// 涂聚文 2017-08-02 小小修改
        /// </summary>
        /// <remarks>
        /// If a <see cref="DateTime"/> property is equal to <see cref="DateTime.MinValue"/> then it means the
        /// date in question was not able to be retrieved. If the <see cref="FtpListItem.Size"/> property
        /// is equal to 0, then it means the size of the object could also not
        /// be retrieved.
        /// </remarks>
        /// <param name="path">The path of the directory to list</param>
        /// <param name="options">Options that dictacte how a list is performed and what information is gathered.</param>
        /// <returns>An array of FtpListItem objects</returns>
        /// <example><code source="..\Examples\GetListing.cs" lang="cs" /></example>
        public FtpListItem[] GetListing(string path, FtpListOption options) {
 
            FtpTrace.WriteFunc("GetListing", new object[] { path, options });
 
            FtpListItem item = null;
            List<FtpListItem> lst = new List<FtpListItem>();
            List<string> rawlisting = new List<string>();
            string listcmd = null;
            string buf = null;
 
            // read flags
            bool isIncludeSelf = (options & FtpListOption.IncludeSelfAndParent) == FtpListOption.IncludeSelfAndParent;
            bool isForceList = (options & FtpListOption.ForceList) == FtpListOption.ForceList;
            bool isNoPath = (options & FtpListOption.NoPath) == FtpListOption.NoPath;
            bool isNameList = (options & FtpListOption.NameList) == FtpListOption.NameList;
            bool isUseLS = (options & FtpListOption.UseLS) == FtpListOption.UseLS;
            bool isAllFiles = (options & FtpListOption.AllFiles) == FtpListOption.AllFiles;
            bool isRecursive = (options & FtpListOption.Recursive) == FtpListOption.Recursive && RecursiveList;
            bool isDerefLinks = (options & FtpListOption.DerefLinks) == FtpListOption.DerefLinks;
            bool isGetModified = (options & FtpListOption.Modify) == FtpListOption.Modify;
            bool isGetSize = (options & FtpListOption.Size) == FtpListOption.Size;
 
            // calc path to request
            path = GetAbsolutePath(path);
 
            // MLSD provides a machine readable format with 100% accurate information
            // so always prefer MLSD over LIST unless the caller of this method overrides it with the ForceList option
            bool machineList = false; //||
            if ((!isForceList & m_parser == FtpParser.Machine) && HasFeature(FtpCapability.MLSD)) {
                listcmd = "MLSD";
                machineList = true;
            } else {
                if (isUseLS) {
                    listcmd = "LS";
                } else if (isNameList) {
                    listcmd = "NLST";
                } else {
                    string listopts = "";
 
                    listcmd = "LIST";
 
                    if (isAllFiles)
                        listopts += "a"; //读取所有文件夹和文件
 
                    if (isRecursive)
                        listopts += "R";
 
                    if (listopts.Length > 0)
                        listcmd += " -" + listopts;
                }
            }
 
            if (!isNoPath) {
                listcmd = (listcmd + " " + path.GetFtpPath());
            }
 
#if !CORE14
            lock (m_lock) {
#endif
                Execute("TYPE I");
                //读取出文件夹或文件 读取所有文件夹和文件 LIST a
                // read in raw file listing
                using (FtpDataStream stream = OpenDataStream(listcmd, 0)) {
                    try {
                        FtpTrace.WriteLine(FtpTraceLevel.Verbose, "+---------------------------------------+");
 
                        if (this.BulkListing) {
 
                            // increases performance of GetListing by reading multiple lines of the file listing at once
                            foreach (var line in stream.ReadAllLines(Encoding, this.BulkListingLength)) {
                                if (!FtpExtensions.IsNullOrWhiteSpace(line)) {
                                    rawlisting.Add(line);
                                    FtpTrace.WriteLine(FtpTraceLevel.Verbose, "Listing:  " + line);
                                }
                            }
 
                        } else {
 
                            // GetListing will read file listings line-by-line (actually byte-by-byte)
                            while ((buf = stream.ReadLine(Encoding)) != null) {
                                if (buf.Length > 0) {
                                    rawlisting.Add(buf);
                                    FtpTrace.WriteLine(FtpTraceLevel.Verbose, "Listing:  " + buf);
                                }
                            }
                        }
 
                        FtpTrace.WriteLine(FtpTraceLevel.Verbose, "-----------------------------------------");
 
                    } finally {
                        stream.Close();
                    }
                }
#if !CORE14
            }
#endif
            //在上循环中读取文件或文件夹属性
            for (int i = 0; i < rawlisting.Count; i++) {
                buf = rawlisting[i];
 
                if (isNameList) {
 
                    // if NLST was used we only have a file name so
                    // there is nothing to parse.
                    item = new FtpListItem() {
                        FullName = buf
                    };
 
                    if (DirectoryExists(item.FullName))
                        item.Type = FtpFileSystemObjectType.Directory;
                    else
                        item.Type = FtpFileSystemObjectType.File;
 
                    lst.Add(item);
 
                } else {
 
                    // if this is a result of LIST -R then the path will be spit out
                    // before each block of objects
                    if (listcmd.StartsWith("LIST") && isRecursive) {
                        if (buf.StartsWith("/") && buf.EndsWith(":")) {
                            path = buf.TrimEnd(':');
                            continue;
                        }
                    }
 
                    // if the next line in the listing starts with spaces
                    // it is assumed to be a continuation of the current line
                    if (i + 1 < rawlisting.Count && (rawlisting[i + 1].StartsWith("\t") || rawlisting[i + 1].StartsWith(" ")))
                        buf += rawlisting[++i];
 
                    try {
                        item = m_listParser.ParseSingleLine(path, buf, m_caps, machineList);
                    } catch (FtpListParser.CriticalListParseException) {
                        FtpTrace.WriteStatus(FtpTraceLevel.Verbose, "Restarting parsing from first entry in list");
                        i = -1;
                        lst.Clear();
                        continue;
                    }
 
                    // FtpListItem.Parse() returns null if the line
                    // could not be parsed
                    if (item != null) {
                        if (isIncludeSelf || !(item.Name == "." || item.Name == "..")) {
                            lst.Add(item);
                        } else {
                            //FtpTrace.WriteStatus(FtpTraceLevel.Verbose, "Skipped self or parent item: " + item.Name);
                        }
                    } else {
                        FtpTrace.WriteStatus(FtpTraceLevel.Warn, "Failed to parse file listing: " + buf);
                    }
                }
 
                // load extended information that wasn't available if the list options flags say to do so.
                if (item != null) {
 
                    // try to dereference symbolic links if the appropriate list
                    // option was passed
                    if (item.Type == FtpFileSystemObjectType.Link && isDerefLinks) {
                        item.LinkObject = DereferenceLink(item);
                    }
 
                    // if need to get file modified date
                    if (isGetModified && HasFeature(FtpCapability.MDTM)) {
 
                        // if the modified date was not loaded or the modified date is more than a day in the future
                        // and the server supports the MDTM command, load the modified date.
                        // most servers do not support retrieving the modified date
                        // of a directory but we try any way.
                        if (item.Modified == DateTime.MinValue || listcmd.StartsWith("LIST")) {
                            DateTime modify;
 
                            if (item.Type == FtpFileSystemObjectType.Directory)
                                FtpTrace.WriteStatus(FtpTraceLevel.Verbose, "Trying to retrieve modification time of a directory, some servers don't like this...");
 
                            if ((modify = GetModifiedTime(item.FullName)) != DateTime.MinValue)
                                item.Modified = modify;
                        }
                    }
 
                    // if need to get file size
                    if (isGetSize && HasFeature(FtpCapability.SIZE)) {
 
                        // if no size was parsed, the object is a file and the server
                        // supports the SIZE command, then load the file size
                        if (item.Size == -1) {
                            if (item.Type != FtpFileSystemObjectType.Directory) {
                                item.Size = GetFileSize(item.FullName); //尺寸要换算一下
                            } else {
                                item.Size = 0;
                            }
                        }
                    }
                }
            }
 
            return lst.ToArray();
        }
 
        /// <summary>
        /// Creates a valid FTP path by appending the specified segments to this string
        /// 涂聚文 2017-08-02 小小修改
        /// </summary>
        /// <param name="path">This string</param>
        /// <param name="segments">The path segments to append</param>
        /// <returns>A valid FTP path</returns>
        public static string GetFtpPath(this string path, params string[] segments) {
            if (String.IsNullOrEmpty(path))
                path = "./";
 
            foreach (string part in segments) {
                if (part != null) {
                    if (path.Length > 0 && !path.EndsWith("/"))
                        path += "/";
                    //path = Regex.Replace(part.Replace('\\', '/'), "[/]+", "/").TrimEnd('/');  //这里重复 path +=
                }
            }
 
            path = Regex.Replace(path.Replace('\\', '/'), "[/]+", "/").TrimEnd('/');
            if (path.Length == 0)
                path = "/";
 
            /*if (!path.StartsWith("/") || !path.StartsWith("./"))
                path = "./" + path;*/
 
            return path;
        }

  

 

 

posted @   ®Geovin Du Dream Park™  阅读(1473)  评论(2编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2016-08-02 csharp: Export DataTable to Excel using OpenXml 2.5 in asp.net
2016-08-02 csharp:asp.net Importing or Exporting Data from Worksheets using aspose cell
2012-08-02 csharp Remove Empty rows in datatable
2012-08-02 csharp read excel file get sheetName list
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示