最近写C#程序时遇到了一个场景,需要分析一个FTP地址各项要素,并将之放到一个Dictionary类中。于是我写了一个函数实现这一功能。
FTP地址语法定义在RFC-1738,格式为:ftp://[user[:password]@]host[:port]/url-path
其中,方括号围住的部分为选填项,user为用户名,password为密码,host为FTP地址,port为FTP端口号,url-path为地址后接的目录地址。
函数AnalyzerFtpUrl代码如下:
/// <summary>
/// 解析FTP地址
/// </summary>
/// <param name="ftpUrl"></param>
/// <returns></returns>
public static Dictionary<string, string> AnalyzeFtpUrl(string ftpUrl)
{
Dictionary<string, string> dic = new Dictionary<string, string>();
if (string.IsNullOrWhiteSpace(ftpUrl) || !ftpUrl.StartsWith("ftp://"))
{
throw new Exception("无效的FTP地址");
}
ftpUrl = ftpUrl.Substring(6); //去除最前面的 ftp://
string userName = ""; //登录用户名
string userPassword = ""; //登录密码
string address = ""; //登录地址
string port = ""; //端口号
string directory = ""; //内部子目录
string leftHalf = ""; //@左侧部分 用户名:密码
string rightHalf = ""; //@右侧部分 登录地址:端口号/内部子目录
//将FTP地址划分为左侧部分与右侧部分
int half = ftpUrl.IndexOf('@');
if (half == -1)
{
leftHalf = "";
rightHalf = ftpUrl;
}
else
{
leftHalf = ftpUrl.Substring(0, half);
rightHalf = ftpUrl.Substring(half + 1);
}
//解析 用户名:密码
if (!string.IsNullOrWhiteSpace(leftHalf))
{
int half2 = leftHalf.IndexOf(':');
if (half2 != -1)
{
userName = leftHalf.Substring(0, half2);
userPassword = leftHalf.Substring(half2 + 1);
if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(userPassword))
{
userName = "";
userPassword = "";
}
}
}
//解析 登录地址:端口号/内部子目录
if (!string.IsNullOrWhiteSpace(rightHalf))
{
int half3 = rightHalf.IndexOf('/');
if (half3 != -1)
{
directory = rightHalf.Substring(half3);
if (directory == "/")
{
directory = "";
}
rightHalf = rightHalf.Substring(0, half3);
}
int half4 = rightHalf.IndexOf(':');
if (half4 == -1)
{
address = rightHalf;
}
else
{
address = rightHalf.Substring(0, half4);
port = rightHalf.Substring(half4 + 1);
}
if (string.IsNullOrWhiteSpace(address))
{
throw new Exception("无效的FTP地址");
}
}
else
{
throw new Exception("无效的FTP地址");
}
//添加字典项
dic.Add("username", userName);
dic.Add("userPassword", userPassword);
dic.Add("address", address);
dic.Add("port", port);
dic.Add("directory", directory);
return dic;
}
建立一个C#命令行应用程序,键入如下代码,其中函数AnalyzeFtpUrl已在上面给出,在此不再赘述。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FtpUrlAnalyzer
{
class Program
{
static void Main(string[] args)
{
PrintItem("ftp://flora:123456@127.0.0.1:1024/hi_flora/");
PrintItem("ftp://127.0.0.1/hi_flora");
PrintItem("ftp://127.0.0.1:1024/hi_flora");
PrintItem("ftp://:@127.0.0.1:1024/");
PrintItem("");
PrintItem("123456");
PrintItem("ftp://tsybius2014");
PrintItem("ftp://:1024/hi_flora");
Console.Read();
}
/// <summary>
/// 打印FTP
/// </summary>
/// <param name="ftpUrl"></param>
public static void PrintItem(string ftpUrl)
{
try
{
Console.WriteLine("url [ " + ftpUrl + " ]");
Console.WriteLine("----------------------");
Dictionary<string, string> dic = AnalyzeFtpUrl(ftpUrl);
foreach (KeyValuePair<string, string> pair in dic)
{
Console.WriteLine("key:" + pair.Key + ", value:" + pair.Value);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
Console.WriteLine();
}
}
/// <summary>
/// 解析FTP地址
/// </summary>
/// <param name="ftpUrl"></param>
/// <returns></returns>
public static Dictionary<string, string> AnalyzeFtpUrl(string ftpUrl)
{
Dictionary<string, string> dic = new Dictionary<string, string>();
//函数实现逻辑同上,故略
return dic;
}
}
}
程序运行结果输出如下:
url [ ftp://flora:123456@127.0.0.1:1024/hi_flora/ ]
----------------------
key:username, value:flora
key:userPassword, value:123456
key:address, value:127.0.0.1
key:port, value:1024
key:directory, value:/hi_flora/
url [ ftp://127.0.0.1/hi_flora ]
----------------------
key:username, value:
key:userPassword, value:
key:address, value:127.0.0.1
key:port, value:
key:directory, value:/hi_flora
url [ ftp://127.0.0.1:1024/hi_flora ]
----------------------
key:username, value:
key:userPassword, value:
key:address, value:127.0.0.1
key:port, value:1024
key:directory, value:/hi_flora
url [ ftp://:@127.0.0.1:1024/ ]
----------------------
key:username, value:
key:userPassword, value:
key:address, value:127.0.0.1
key:port, value:1024
key:directory, value:
url [ ]
----------------------
System.Exception: 无效的FTP地址
在 FtpUrlAnalyzer.Program.AnalyzeFtpUrl(String ftpUrl) 位置 d:\MyPrograms\Ftp
UrlAnalyzer\FtpUrlAnalyzer\Program.cs:行号 61
在 FtpUrlAnalyzer.Program.PrintItem(String ftpUrl) 位置 d:\MyPrograms\FtpUrlA
nalyzer\FtpUrlAnalyzer\Program.cs:行号 34
url [ 123456 ]
----------------------
System.Exception: 无效的FTP地址
在 FtpUrlAnalyzer.Program.AnalyzeFtpUrl(String ftpUrl) 位置 d:\MyPrograms\Ftp
UrlAnalyzer\FtpUrlAnalyzer\Program.cs:行号 61
在 FtpUrlAnalyzer.Program.PrintItem(String ftpUrl) 位置 d:\MyPrograms\FtpUrlA
nalyzer\FtpUrlAnalyzer\Program.cs:行号 34
url [ ftp://tsybius2014 ]
----------------------
key:username, value:
key:userPassword, value:
key:address, value:tsybius2014
key:port, value:
key:directory, value:
url [ ftp://:1024/hi_flora ]
----------------------
System.Exception: 无效的FTP地址
在 FtpUrlAnalyzer.Program.AnalyzeFtpUrl(String ftpUrl) 位置 d:\MyPrograms\Ftp
UrlAnalyzer\FtpUrlAnalyzer\Program.cs:行号 131
在 FtpUrlAnalyzer.Program.PrintItem(String ftpUrl) 位置 d:\MyPrograms\FtpUrlA
nalyzer\FtpUrlAnalyzer\Program.cs:行号 34
END