您的位置:首页 > 编程语言 > PHP开发

FTP服务器LIST指令获取的文件列表信息解析(UNIX格式)

2014-03-03 12:22 387 查看
最近在写FTP客户端的程序,但是在发送LIST指令之后,不知如何解析服务器发回的列表信息,上网一查,略坑,居然都是同一篇文章,居然还都是原创,而且对于UNIX格式下的文件列表信息并没有解析完成,因为没有判断出文件的年份,附带的程序也不完善。

经过几翻查找资料,终于知道了正确的解析方法,与各位同道一起分享,请各位指正。

FTP服务器运行的系统一般分为windows和UNIX操作系统,系统不一样,FTP服务器返回的信息也不一样,有两种格式,如下:

1、MS-DOS文件列表格式解析:

这种格式的讲解就略过了,百度很容易就找到了。

2、现在看UNIX文件列表格式的解析:

UNIX文件列表格式解析:

drwx----- 1 user group            0   Sep 20 18:50 360Rec

-rwx------ 1 user group           24 Jun 11 2009 autoexec.bat

drwx----- 1 user group            0  Jul 14 2009 Documents and Settings

drwx----- 1 user group            0 Feb 08 2013 User

drwx----- 1 user group            0 Jun 28 22:16 Users

以上是我在编程时服务器返回的部分文件列表信息。

UNIX文件列表每一个文件信息分为9个部分,现在说每个部分代表的意义:

第一部分drwx-----,共9个字符,第一个字符d表示该文件是目录,-表示是文件,之后的r表示可读,w表示可写,x表示可执行

第二部分,第二部分,第三部分,对我来说意义不大,略过不提

第五部分:如果是目录,则为0(<DIR>),如果是文件,则为文件大小

第六部分:文件的月份

第七部分:文件的月份的某一天

第八部分:或者为小时分钟,或者为年份

第九部分:文件名

信息提取方式,以提取第一部分信息为例:

CString msg = "drwx----- 1 user group            0   Sep 20 18:50 360Rec",str;
msg.TrimLeft();//去掉左侧的空格,制表符,回车
int n = msg.Find(" ");//查找第一个空格,返回空格的位置,或者-1
str = msg.Left(n);//将msg中第n个位置左侧的字符赋值给str,提取了第一部分信息
msg = msg.Mid(n+1);//将msg中第n个位置之后的所以字符赋值给msg


循环解析……,即可得到所有部分的信息。

现在说文件时间信息的处理:

我想大家应该在纠结第八部分如何处理,如何得到具体的年份,如果第八部分为年份,自然万事大吉,如果不是年份,我们怎么得到年份呢?其实文件列表信息是有具体规定的。我们再处理时间时,必须与当前的时间进行比较,这里的当前时间是指:程序的运行的具体时间。

如果第八部分为HH:MM(H:小时,M:分钟)格式,获取当前时间的年year、月month和日day(2014年3月3日),比较文件列表中的月份和当前月份,比如第一个文件列表信息中的月份是Sep,9月大于当前月份3月,那么该文件的年份就是当前年份-1,即是2013年;如果小于当前月份,那么该文件的年份就是当前年份。

这样就算第八部分是HH:MM,我们也能得到文件的年份了。

以下是我的解析函数:

while(1)//处理整个文件列表信息
{//整个文件列表信息中,每个文件信息是以"\r\n"来隔开的
n = st.Find("\r\n");//查找st中第一个"\r\n"的位置
if(n == -1)//若不存在,则结束循环
break;
filelist = st.Left(n);//将st中从0开始到第一个"\r\n"的字符串赋值给filelist,即第一个文件信息
st = st.Mid(n+2);//将st从第一个"\r\n"的位置开始,到结束的字符赋值给st,即保留剩余文件信息
if(filelist[0] == 'd')
{
//若为目录,相应处理程序
}
else
{
//若为文件,相应处理程序
}
}
CString GetSegmentInfo(CString sFileInfo,int nSegment)//分割文件信息,第一个形参是某个文件的信息,第二个形参是提取的第几部分,从0开始,到8结束
{
int nIdx = -1;
int nSeg = 0;
CString sInfo = "";
sFileInfo.TrimLeft();//消除前导的空格,制表符,换行符
while(nSeg < nSegment+1)//逐段切隔
{
nIdx = sFileInfo.Find(" ");//以空格为切隔
sInfo = sFileInfo.Left(nIdx);
if(nSeg < nSegment)//文件名有空格时也可以分割出来
sFileInfo = sFileInfo.Mid(nIdx+1);//如果提取的是文件名,最后一次Mid不能执行,否则当文件名中有空格时,得到的文件名不对
sFileInfo.TrimLeft();//过滤左侧的空格符
nSeg++;
}
if(nSegment == 8)
sInfo = sFileInfo;
return sInfo;
}

CString GetTime(CString month,CString day,CString tt)//解析文件的年月日
{
CString mon[12] ={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"},filetime;
CTime _time=time(NULL);
int mm = 0,year,dd = atoi(day);
for(int i = 0;i < 12; i++)
{
if(month == mon[i])
{
mm = i+1;//取得文件信息中的月份
break;
}
}
if(tt.Find(':') == -1)//如果第八部分中没有字符':',则第八部分是年份
year = atoi(tt);
else//如果不是年份
{
if(mm > _time.GetMonth())//若大于当前月份,则年份为当前年份-1
year = _time.GetYear()-1;
else//否则为当前年份-1
year = _time.GetYear();
}
filetime.Format("%d/%d/%d",year,mm,dd);
return filetime;
}


转载注明出处:http://blog.csdn.net/love_feng_forever/article/details/20362469
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息