最近因需要拓展音乐播放器功能,研究了下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, 00&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;
    }
}

 

 

 

 

相关文章:

  • 2022-12-23
  • 2021-08-10
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案