您的位置:首页 > 其它

遍历Symbian某目录下的所有文件

2007-05-18 10:10 447 查看
遍历Symbian某目录下的所有文件应该是Symbian中常用到的功能模块,比如你想写一个类似“程序管理器”的程序,那么首先的任务就是要先知道某目录下到底有那些文件,然后再筛选出你所需要的文件。
遍历Symbian某目录下的所有文件有两种方法

我们首先学习点预备知识
查看SDKHELP中的GetDir()方法,你会看到如下的内容:
GetDir()
TIntGetDir(constTDesC&aName,TUintanEntryAttMask,TUintanEntrySortKey,CDir*&anEntryList)const;
Description
Getsafilteredlistofadirectory'scontents.Thebitmaskdetermineswhichfileanddirectoryentrytypesshouldbelisted.Thesortkeydeterminestheorderinwhichtheyarelisted.
注释
得到一个目录下内容的过滤列表。
anEntryAttMask决定哪个文件和目录应该被列出。
anEntrySortKey决定这些内容按照什么顺序列出。
Notes:

IfsortingbyUID(ESortByUidisOR'edwiththeentrysortkey),thenUIDinformationwillbeincludedinthelistingwhetherornotKEntryAttAllowUidisspecifiedinanEntryAttMask.(如果按照UID排序,即anEntrySortKey参数的值定义为ESortByUid。那么UID信息将被包含在列表中不管anEntryAttMask参数是否定义了KEntryAttAllowUid)

ThefunctionsetsanEntryListtoNULL,thenallocatesmemoryforitbeforeappendingentriestothelist.Therefore,anEntryListshouldhavenomemoryallocatedtoitbeforethisfunctioniscalled,otherwisethismemorywillbecomeorphaned.(这个函数把anEntryList参数设置为NULL,然后在添加文件项到列表之前为anEntryList分配内存空间。因此,该函数调用之前anEntryList应该没有分配内存,否则这部分内存会变成垃圾而被遗弃)

ThecallerofthisfunctionisresponsiblefordeletinganEntryListafterthefunctionhasreturned.(此函数的调用者有责任删除anEntryList在函数返回)

Parameters
constTDesC&aName
Nameofthedirectoryforwhichalistingisrequired.Wildcardsmaybeusedtospecifyparticularfiles.
TUintanEntryAttMask
Bitmaskindicatingtheattributesofinterest.Onlyfilesanddirectorieswhoseattributesmatchthosespecifiedherecanbeincludedinthelisting.FormoreinformationseeKEntryAttMatchMaskandtheotherdirectoryentrydetails.AlsoseeKEntryAttNormalandtheotherfileordirectoryattributes.
TUintanEntrySortKey
Flagindicatingtheorderinwhichtheentriesaretobesorted.ThisflagisdefinedinTEntryKey.
CDir*&anEntryList
Onreturncontainsalistofdirectoryandfileentries.
Returnvalue
TInt
KErrNoneifsuccessful,otherwiseanotherofthesystem-wideerrorcodes.
这是
RFs
类中的一个方法,从上面的SDKHELP内容我们可以看出:如果我们想获取某个目录下的所有内容,那么只需获取相应目录的CDir指针即可。

那么我们再看看CDir这个类的SDKHELP:

Class
CDir

CDir

Support

Supportedfrom5.0

Description

Arrayofdirectoryentriesthathasbeenreadintomemoryfromthefilesystem—abstractbaseclass.Itcanbereadandsortedbyuserprograms,butcannotbecreatedbythem.
Thisclassisnotintendedforuserderivation.
注释:一个数组,这个数组的内容是从文件系统扫描到的目录,目录被缓存到内存中。它可以被我们的程序读取和排序,但是不能创建。

Derivation

o
CBase
-Baseclassforallclassestobeinstantiatedontheheap
§
CDir
-Arrayofdirectoryentriesthathasbeenreadintomemoryfromthefilesystem—abstractbaseclass

Members

Definedin
CDir
:
Count()
,
NewL()
,
Sort()
,
operator[]()
,
~CDir()

Inheritedfrom
CBase
:
operatornew()

可见,这个类派生自CBase,并且继承了CBase的new()运算符。它里面只有5个方法,去处析构函数,实际上只有4个有用的方法。并且它里面重新定义了[]操作符,因为CDir本身是一个目录的数组。它还可以排序、可以计算数量,这些都是数组的基本特性。NewL()只不过也是一个重载的运算符而已。

再看看operator[]()的定义:

operator[]()
constTEntry&operator[](TIntanIndex)const;
Description
Returnsanentryfromthearray.
Parameters
TIntanIndex
Indexofthedesiredentrywithinthearray.
Returnvalue
TEntry&
Adirectoryentry.
可以看出,通过[]操作符,CDir指针返回给我们的是一个目录的封装类
TEntry。


我们可以再跟踪一下TEntry这个类的SDKHELP:

Class
TEntry

TEntry

Support

Supportedfrom5.0

Description

Encapsulatesanentryinadirectory,whichcanbeanother(nested)directory,afileoravolumelabel.Eachdirectoryentryhasanamewhichisrelativetoitsowningdirectoryandatype,whichisindicatedbyitsuniqueidentifier(UID).
注释:封装目录中的一项内容,内容可以是另一个(嵌套的)目录、一个文件或者是一个驱动器卷标。每个目录项都有一个名字和类型与它的所属目录相关联,也就是UID所显示出来的东西。
Anentrycanbeinterrogatedforthefollowingproperties:
一项内容可以被提取以下的属性:
·thekindofentry:storedintheentryUIDs,storedin
iType
(项的类型:储存在UIDs和iType中)
·theentryattributes,storedin
iAtt
(项的属性:储存在iAtt中)
·thesizeofentry(项的尺寸)
·thetimetheentrywaslastmodified(项上次被修改的时间)

Members

Definedin
TEntry
:
IsArchive()
,
IsDir()
,
IsHidden()
,
IsReadOnly()
,
IsSystem()
,
IsTypeValid()
,
IsUidPresent()
,
MostDerivedUid()
,
iAtt
,
iModified
,
iName
,
iSize
,
iType
,
operator[]()

Seealso:

Fileordirectoryattributes



通过以上SDKHELP的内容,我们就知道了大概的方向,从而尝试写出了以下的程序:

voidCCountEntryAppUi::ConstructL()
{
BaseConstructL();

RFsiFs;
User::LeaveIfError(iFs.Connect());
_LIT(KDIR,"C://");
CDir*dir;
User::LeaveIfError(iFs.GetDir(KDIR,KEntryAttNormal|KEntryAttMatchMask,ESortByDate,dir));
TInttempInt=dir->Count();
for(inti=0;i<tempInt;i++)
{
TEntry&iEntry=(TEntry&)dir[i];
TBufC<256>iFileName=iEntry.iName;
}

deletedir;
dir=NULL;

iAppContainer=new(ELeave)CCountEntryContainer;
iAppContainer->SetMopParent(this);
iAppContainer->ConstructL(ClientRect());
AddToStackL(iAppContainer);
}
通过设置断点进行观察,可以看到如下结果:



而Symbian系统C盘下的文件内容如下:



可见,此时程序所读取到的文件数目是正确的。

下面我们来看第二中获取Symbian某目录下所有文件的方法,其基本原理是类似的,只不过是调用了不同的接口而已。
RFsiFs;
User::LeaveIfError(iFs.Connect());
_LIT(KDIR,"C://");

RDiroDir;
oDir.Open(iFs,KDIR,KEntryAttNormal);
TEntryArray*oArray=new(ELeave)TEntryArray;
oDir.Read(*oArray);
TIntiCount=oArray->Count();

for(TInti=0;i<iCount;i++)

{
TEntrytemp=(*oArray)[i];
TNameiTemp=temp.iName;

if(i==2)
CEikonEnv::Static()->InfoMsg(iTemp);
}
iFs.Close();
和第一种方法不同的是,这里使用了RDir类作为目录项的存放数组。我们看看SDKHELP中这个类的帮助文档:
RDir
Support
Supportedfrom5.0
Description
Readstheentriescontainedinadirectory.
读取一个目录中所包含的项,包括目录、文件以及驱动器卷标,这一点和上面的CDir类是一样的。
Youmustfirstopenthedirectory,specifyinganattributemaskwhichisusedbyRead()callstofiltertheentrytypesrequired.Then,useoneoftheRead()functionstoreadthefilteredentries.Whentheoperationiscomplete,thedirectoryshouldbeclosedusingClose(),definedinthebaseclassRFsBase.
你必须先打开目录,定义一个属性掩码用来过滤项类型。然后用Read()函数去读取过滤的项。当操作完成时,目录应该调用基类RFsBase中定义的Close()方法关闭。
TherearetwotypesofRead():oneworkswithasingleentryatatime,requiringprogramstoiteratethroughtheentriesexplicitly.TheotherworkswithanentireTEntryArray,allowingmultipleentriestobereadinonecall.Aswellasmakingapplicationprogramlogicsomewhatsimpler,thistypeusesfewercallstotheserver,andismoreefficient.
有两种版本的Read()方法:一种是每次读取一个目录项,要求遍历所有目录项。另一种利用一个TEntryArray工作,它允许多个目录项一次读取完。为了让应用程序逻辑简单,这种类型和服务器的交互少,并且非常高效。
EachtypeofRead()canbeperformedeithersynchronouslyorasynchronously.
每种版本的Read()方法都可以表现为同步的或者异步的。
ItmaybemoreconvenienttouseRFs::GetDir()thantheRead()callssupportedbythisclass.RFs::GetDir()hastheadvantagethatitallowsadirectory'sentriestobesortedinvariousways.However,itdoesnotprovideasynchronousaswellassynchronousvariantsanddoesnotallowentriestobereadindividually.
RFs::GetDir()比这个类所提供的方法更方便,而且RFs::GetDir()允许一个目录的项以不同的方式排序。尽管如此,RFs::GetDir()却不区分同步、异步的方式,并且不允许目录项逐个的读取。
Derivation


RSubSessionBase-Client-sidehandletoasub-session

RFsBase-BaseclassthatprovidesaClose()functionforfilerelatedclean-up

RDir-Readstheentriescontainedinadirectory









Members
DefinedinRDir:
Open(),Open(),Read(),Read(),Read(),Read()
InheritedfromRFsBase:
Close()
InheritedfromRSubSessionBase:
CloseSubSession(),CreateSubSession(),Send(),SendReceive(),SubSessionHandle(),operator=()
看到这里,再和第一种方法进行比较,就应该很容易明白开头所给出的代码了,这段代码在VS2003+Carbide.vs+S60_2nd_FP2_SCSDK中也编译通过.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: