7.45. 长文件名使用注意说明

Overview

提供长文件名的使用及注意事项

7.45.1. 打开或创建长文件名说明

//暂时仅适用于纯ascii码的长文件名和目录,不适用于中文,中文名请自行手动拼接
int long_file_name_encode(const char *input, u8 *output, u32 output_buf_len);        //返回拼接后的长度
  • 1.实现中文名长文件名打开或创建具体实现例程 apps/common/example/storage/sd_fs/main1.c

  • 2.长文件名中的字符采用unicode(UTF16LE)形式编码,每个字符占据2字节的空间

  • 3.下列代码中file_name字符串数组中

  • ‘/’ 目录分隔符

  • ‘\’, ‘U’,使用unicode编码

  • ‘/’,0x00 使用unicode两个字节编码,目录分隔符补充0x00才能被识别到

  • 打开已有文件,unicode编码的扩展名与原名大小写要相同,不然会打开失败

//文件名:longfilename.txt  通过字符转UTF16LE编码写入
char file_name[128] = {'/', '\\', 'U', 0x6C, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x2E, 0x00, 0x74, 0x00, 0x78, 0x00, 0x74, 0x00};

//文件名:hello/测试创建长文件名测试.txt
//char file_name[128] = {'/','h', 'e','l','l','o','/','\\','U',0x4B,0x6D,0xD5,0x8B,0x1B,0x52,0xFA,0x5E,0x7F,0x95,0x87,0x65,0xF6,0x4E,0x0D,0x54,0x4B,0x6D,0xD5,0x8B,0x2E,0x00,0x74,0x00,0x78,0x00,0x74,0x00};

//文件夹名:测试创建长文件名测试
//char file_name[128] = { '/','\\','U',0x4B,0x6D,0xD5,0x8B,0x1B,0x52,0xFA,0x5E,0x7F,0x95,0x87,0x65,0xF6,0x4E,0x0D,0x54,0x4B,0x6D,0xD5,0x8B};


//  测试长文件夹名测试/测试创建长文件名测试.txt
/* char file_name[128] = {'/', '\\', 'U', 0x4B, 0x6D, 0xD5, 0x8B, 0x7F, 0x95, 0x87, 0x65, 0xF6, 0x4E, 0x39, 0x59, 0x0D, 0x54, 0x4B, 0x6D, 0xD5, 0x8B, '/', 0x00, '\\', 'U', 0x4B, 0x6D, 0xD5, 0x8B, 0x1B, 0x52, 0xFA, 0x5E, 0x7F, 0x95, 0x87, 0x65, 0xF6, 0x4E, 0x0D, 0x54, 0x4B, 0x6D, 0xD5, 0x8B, 0x2E, 0x00, 0x74, 0x00, 0x78, 0x00, 0x74, 0x00}; */
  • 4.拼接路径名称

char path[256] = "storage/sd0/C";//路径
memcpy(path + strlen(path), file_name, sizeof(file_name)); //将文件名file_name复制到path路径后
    1. 使用fopen打开长文件名进行使用

fd = fopen(path, "w+");//打开可 读/写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。

7.45.2. 使用长文件名说明

  • 1.打开已有长文件名文件,unicode编码的扩展名与源文件扩展名原名大小写要相同,不然会打开失败

  • 2.使用fget_name获取长文件名长度,注意参数 namelen 的设置不然会获取到短文件名,获取后使用put_buf打印文件名,不要用printf(遇到0会停止)

/**
 * @brief 获取文件名(不包含目录)
 *
 * @param file 指向文件流的文件指针
 * @param name 保存文件名的buffer,获取长文件名时buffer大小要大于长文件名长度,否则会获取到文件的短文件名"LFN~xxx",打印长文件名用put_buf方式
 * @param len buffer的长度,大于15个字节获取的是长文件名,小于16个字节获取的是短文件名
 *
 * @return 文件名的长度(大于0)
 */
int fget_name(FILE *file, u8 *name, int len);
  • 3.使用frename将文件重命名为长文件名。将短文件名rename成长文件名,注意在创建短文件名后要将短文件名fclose后再打开进行rename,直接在创建的短文件中rename会导致长度不对应重命名失败

/**
 * @brief 重命名文件
 *
 * @param file 指向文件流的文件指针
 * @param path 文件的新文件名,不需要加目录路径
 *
 * @return 0: 成功
 * @return other: 失败
 * @note  操作完毕后需要调用fclose关闭文件句柄
 */
int frename(FILE *file, const char *fname);
  • 4.使用fget_attrs获取长文件名创建/修改/访问时间,SDK版本V1.1.x及以前,创建文件后需要fclose,之后进行fget_attrs才能获取到长文件名创建/修改/访问时间,不然会显示未赋值默认时间“1980-0-0-0-0-0”

/**
 * @brief 文件属性
 */
struct vfs_attr {
   u8 attr;                                    /*!< 文件属性标志位 */
   u32 fsize;                                  /*!< 文件大小 */
   u32 sclust;                                 /*!< 最小分配单元 */
   struct sys_time crt_time;   /*!< 文件创建时间 */
   struct sys_time wrt_time;   /*!< 文件最后修改时间 */
   struct sys_time acc_time;   /*!< 文件最后访问时间 */
};

/**
 * @brief 获取文件的详细信息如属性、簇号、大小等
 *
 * @param file 指向文件流的文件指针
 * @param attr 保存操作成功后文件的详细信息
 *
 * @return 0: 获取成功
 * @return other: 获取失败
 */
int fget_attrs(FILE *file, struct vfs_attr *attr);