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

MTK优美代码赏析7:文件搜索与匹配

2010-10-10 12:06 429 查看
最近因需要拓展音乐播放器功能,研究了下MTK的文件系统,趁周末我总结一下关于文件系统关键的接口<文件搜索与匹配>MTK实现的方法。
关于文件搜索,因为都是基于FAT格式的系统,所以MTK文件处理的思路和Window是很相似的。
通过FindFirstFile函数获取操作句柄HANDLE,将此句柄作为参数传入FindNextFile函数,通过FindNextFile不断搜索下一个文件/文件夹,当FindNextFile返回值为0时表示搜索完成,查询完成后通过FindClose关闭句柄。
对应MTK中的接口为FS_FindFirst,FS_FindNext和FS_FindClose,下面拿一段代码来看(来自aud_vr_sd.c)

//作者:张素丰,转载请注明出处:http://www.zhangsufeng.cn/?p=237

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

* FUNCTION

* aud_vr_sd_scan_tags_in_group_folder

* DESCRIPTION

* vr sd scan all tags in a group folder

* PARAMETERS

* group_id [IN]

* path [?]

* RETURNS

* void

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

void aud_vr_sd_scan_tags_in_group_folder(kal_uint16 group_id, kal_uint16 *path)

{

/*----------------------------------------------------------------*/

/* Local Variables */

/*----------------------------------------------------------------*/

kal_uint16 filename[VR_MAX_DB_PATH_LEN + 1];

kal_uint16 filename_expr[VR_MAX_DB_PATH_LEN + 1];

kal_int32 word_id;

FS_HANDLE fd_cursor;

FS_DOSDirEntry file_info;

/*----------------------------------------------------------------*/

/* Code Body */

/*----------------------------------------------------------------*/

vr_sd_ctx.id_length[group_id] = 0;

kal_wsprintf(filename_expr, "%wMTKVR_????.vrd", path);

if ((fd_cursor = FS_FindFirst(filename_expr, 0, 0, &file_info, filename, (VR_MAX_DB_PATH_LEN + 1) << 1)) >= 0)

{

/* loop through all vrd files in a group folder */

do

{

/* filter out folder results */

if (!(file_info.Attributes & FS_ATTR_DIR))

{

/* parse word id and add to id array and increment id length */

if ((word_id = aud_vr_sd_extract_word_id(filename)) >= 0)

{

vr_sd_ctx.id_array[group_id][vr_sd_ctx.id_length[group_id]++] = word_id;

}

}

} while (FS_FindNext(fd_cursor, &file_info, filename, (VR_MAX_DB_PATH_LEN + 1) << 1) == FS_NO_ERROR);

FS_FindClose(fd_cursor);

}

}

下面讲一讲匹配,这里所说的匹配主要是将文件格式(即后缀名)的匹配,在获取到文件名以后进行。

思路也都是相同的,那就是从文件名末端开始搜索到第一个".",然后截取"."后面这一段作为拓展名,然后把这个拓展名拿到自己的需要的格式列表中对比即可。

MTK中有两种方式实现了这个需求,

方式1(来自FileManagerSrc.c):

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

* FUNCTION
* mmi_fmgr_get_file_group
* DESCRIPTION
* check file type belongs to which file group
* PARAMETERS
* path [?]
* RETURNS
* void
*****************************************************************************/
U8 mmi_fmgr_get_file_group(S8 *path)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
FMGR_FILTER file_type;
S32 result;

/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
result = mmi_fmgr_get_file_type(path, &file_type);

if (result == FS_FILE_NOT_FOUND)
{
return FMGR_GROUP_UNKNOWN;
}

if (FMGR_FILTER_IS_SET_AUDIO(&file_type))
{
return FMGR_GROUP_AUDIO;
}
else if (FMGR_FILTER_IS_SET_IMAGE(&file_type))
{
return FMGR_GROUP_IMAGE;
}
else if (FMGR_FILTER_IS_SET_VIDEO(&file_type))
{
return FMGR_GROUP_VIDEO;
}
else if (FMGR_FILTER_IS_SET_SWFLASH(&file_type))
{
return FMGR_GROUP_SWFLASH;
}
else
{
return FMGR_GROUP_UNKNOWN;
}
}

在mmi_fmgr_get_file_type函数内实现了相应的逻辑,这个流程依赖于FileMgr.c中

const fmgr_filter_struct fmgr_filter[FMGR_MAX_FILTER_COUNT];

方式2: 依赖于系统的全局变量的东西有时并不能满足我们应用的需求,这个时候我们需要自己定义一个私有的fmgr_filter,来实现拓展名的判断。

这个流程的实现可以参照09A代码AudioPlayerPlayList.c中mmi_audply_playlist_generate_search函数。

下面来对比两个获取后缀名的函数:

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

* FUNCTION
* mmi_fmgr_extract_ext_file_name
* DESCRIPTION
* get pointer to the extension file name in the file path
* PARAMETERS
* path [?]
* RETURNS
* void
*****************************************************************************/
PS8 mmi_fmgr_extract_ext_file_name(S8 *path)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S16 i, length;

/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
length = (S16) mmi_ucs2strlen(path);
i = length - 1;

while (i >= 0)
{
if (path[i << 1] == '\\' && path[(i << 1) + 1] == 0)
{
return NULL;
}
if (path[i << 1] == '.' && path[(i << 1) + 1] == 0 && (i != length - 1))
{
break;
}
i--;
}

if (i < 0)
{
return NULL;
}

return &path[(i + 1) << 1];
}

另一种系统string处理的接口:

/*****************************************************************************
* FUNCTION
* app_ucs2_strrchr
* DESCRIPTION
* Scan a UCS2 encoded string for the last occurrence of a character.
* PARAMETERS
* string [IN] UCS2 encoded string to search in.
* ch [IN] UCS2 encoded wide-character to search for.
* RETURNS
* returns pointer to the last occurrence of ch in string
* returns NULL if ch does not occur in string
*****************************************************************************/
kal_int8 *app_ucs2_strrchr(const kal_int8 * string, kal_wchar ch)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_int8 *cursor = (kal_int8 *)string;

/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
while (*cursor || *(cursor+1)) /* find end of string */
{
cursor += 2;
}

/* search towards front */
while ((kal_int8 *)string != cursor &&
(*(cursor+1)<<8|(kal_uint8)(*cursor)) != ch)
{
cursor -= 2;
}

if ((*(cursor+1)<<8|(kal_uint8)(*cursor)) == ch) /* found ?*/
{
return cursor;
}

return NULL;
}
PS8 test(const UI_string_type ext)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U8 i = 0;
U32 ext_len = 0;
UI_character_type file_ext[FMGR_MAX_EXT_LEN + 1];
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
/* skip ".". */
{
PS8 dot = (PS8)app_ucs2_strrchr((const PS8)ext, (U16)L'.');
if (dot)
{
dot += 2;
}
else
{
dot = (PS8)ext;
}
mmi_ucs2ncpy((PS8)file_ext, (const PS8)dot, FMGR_MAX_EXT_LEN);
ext_len = mmi_ucs2strlen((const PS8)dot);
return dot;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: