分享
 
 
 

FTP服务的LIST指令获取的文件列表信息的解析

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

客户端使用LIST命令指定获取服务器端FTP共享目录(或者下面的子目录),服务器端将通过数据端口将该指定目录下的文件列表(包括子目录)信息发送给客户端。本文对该文件列表信息进行分析和解析。

文件列表信息分为UNIX格式和DOS格式两种。笔者是比照了Serv-U和微软自带的FTP服务器写出本文的,也许别的服务器另有新的方式或者格式也说不定,欢迎大家补充。

首先不妨来看一下UNIX格式和DOS格式下的文件列表信息都是怎么样的:

//MS-DOS文件列表格式解析

//02-23-05 09:24AM 2245 readme.ESn

//05-25-04 08:56AM 19041660 VC.ESn

UNIX文件列表格式解析

UNIX文件格式:

Serv-U:

-rwxrw-r-- 1 user group 3014 Nov 12 14:57 cwinvnc337.ESn

-rwxrw-r-- 1 user group 20480 Mar 3 11:25 inmcsvr更新说明.ESn

-rwxrw-r-- 1 user group 450 Apr 13 11:39 对话框中加入工具条.ESn

Windows自带FTP:

-rwxrwxrwx 1 owner group 19041660 May 25 2004 VC.ESn

-rwxrwxrwx 1 owner group 450 Apr 6 15:04 对话框中加入工具条.ESn

注:由于未发现Serv-U支持DOS格式,因此DOS格式只列了微软自带的。

下面我们对以上的格式进行分析:

首先,文件列表信息中,每个文件的信息之间用回车换行符(\r\n)分隔。因此分解时第一步就是用\r\n进行截取。然后是对每一个文件信息的解析。

每一个文件信息中,分为多个信息段,各个信息段之间用一个空格符间隔。UNIX格式和DOS格式的信息段的数量的顺序是不同的。下面将分别分析。

先看看DOS格式,拿出一条文件信息来讲:02-23-05 09:24AM 2245 readme.ESn

第一段为05-25-04,一个空格后,为第二段08:56AM,一个空格后,为 19041660,由于文件长度不一定,预留的位置比较长,因此前面用空格填充了。

解析的时候,逐段用空格截取,记住,截取完第一段后,剩下的内容先用TrimLeft去除左侧的空格,然后继续截取就可以了。

因此,DOS格式共分四段,其中第一段为日期,第二段为时间,第三段为文件长度,第四段为文件名称。

对了,如果只需要获取文件名称,你也不能从后面截取,因为文件名称是允许带空格的。:》

另外,如果列举的是个目录,那么,第三段就不是文件长度了,而是固定为:<DIR>

再看UNIX格式,也拿出一条文件信息来讲:

-rwxrw-r-- 1 user group 3014 Nov 12 14:57 cwinvnc337.ESn

unix我不熟,每一段的意义不太清楚。但以上的格式分解为:第一段为-rwxrw-r--,第二段为1,第三段为user,第四段为group,第五段为文件长度,第六段为月,第七段为日,第八段为时间,第九段为文件名称。

需要注意的是:如果格式串的第一个字符为d,表示为一个目录信息,比如drwxrw-r--

另外,第八段有可能不是时间,而是年份,比如2005,从上面的例子中你可以发现。

对于不同的FTP服务器,LIST获取的信息不尽相同,但段的顺序和意义是不变的。只是表示文件的长度的段的长度有所不同。

以下是笔者在实际项目中的解析函数,做的不是很好,但希望对大家有所帮助吧。

/***************************************************

Function: CRecvFileMan::PraseFileList_MSDOS

Description: 解析MSDOS风格的文件列表

Table Accessed:

Table Updated:

Parameter: CString sFileList - MSDOS风格文件列表

Return: 无返回值

Others:

***************************************************/

void CRecvFileMan::PraseFileList_MSDOS(CString sFileList)

{

CString sLen;

CString sFile;

CString sOneFile;

int nIdx = 0;

while(1)

{

nIdx = sFileList.Find("\r\n");

if(nIdx == -1)

break;

sOneFile = sFileList.Left(nIdx);

sFileList = sFileList.Mid(nIdx + 2);

sLen = GetSegmentInfo(sOneFile,2);

if(sLen == "<DIR>")

{

continue;

}

sFile = GetSegmentInfo(sOneFile,0);

//根据解析的文件信息,形成下载文件类对象

CRecvFile *pFile = new CRecvFile(sFile,atoi(sLen));

m_arTransFile.Add(pFile);

};

}

/***************************************************

Function: CRecvFileMan::PraseFileList_UNIX

Description: 解析UNIX风格的文件列表

Table Accessed:

Table Updated:

Parameter: CString sFileList - UNIX风格文件列表,以回车换行分隔

Return: 无返回值

Others:

***************************************************/

void CRecvFileMan::PraseFileList_UNIX(CString sFileList)

{

CString sLen;

CString sFile;

CString sOneFile;

int nIdx = 0;

while(1)

{

nIdx = sFileList.Find("\r\n");

if(nIdx == -1)

break;

sOneFile = sFileList.Left(nIdx);

sFileList = sFileList.Mid(nIdx + 2);

if(sOneFile.GetAt(0) == 'd')//第一个字母是d,表示是目录,忽略

continue;

sLen = GetSegmentInfo(sOneFile,4);

sFile = GetSegmentInfo(sOneFile,3);

//根据解析的文件信息,形成下载文件类对象

CRecvFile *pFile = new CRecvFile(sFile,atoi(sLen));

m_arTransFile.Add(pFile);

};

}

/***************************************************

Function: CRecvFileMan::GetSegmentInfo

Description: 得到文件列表中某个文件描述的指定段的信息

Table Accessed:

Table Updated:

Parameter: CString &sFileInfo - 指定的文件描述信息。即是传入,也是传出参数

将获取段号信息后剩余的信息返回,以便进一步截取其它信息

int nSegment - 指定的段号,从0开始

Return: CString - 指定段号的信息

Others:

***************************************************/

CString CRecvFileMan::GetSegmentInfo(CString &sFileInfo,int nSegment)

{

int nIdx = -1;

int nSeg = 0;

CString sInfo = "";

sFileInfo.TrimLeft();

while(nSeg < nSegment + 1)//逐段切隔

{

nIdx = sFileInfo.Find(" ");//以空格为切隔

if(nIdx < 0)//如果已没有空格,即最后一段信息

{

if(nSeg == nSegment)//如果最后一段正好是需要的段

{

sInfo = sFileInfo;//返回剩余信息

}

else

sInfo = "";

break;

}

else

{

sInfo = sFileInfo.Left(nIdx);//得到段信息

sFileInfo = sFileInfo.Mid(nIdx+1);//切隔信息

sFileInfo.TrimLeft();//过滤左侧的空格符

}

nSeg++;

}

return sInfo;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有