搜索
bottom↓
回复: 35

关于 FATFS 能否支持 中文文件名 ,请教

[复制链接]

出0入0汤圆

发表于 2009-9-4 10:01:44 | 显示全部楼层 |阅读模式
最近在看FATFS,需要读取文件名为 汉字 的文件,调试发现:
f_readdir (
    DIR *dirobj,        /* Pointer to the directory object */
    FILINFO *finfo        /* Pointer to file information to return */
)可以正常读取 汉字 文件名;如“绿色.txt”

但打开文件时
f_open (
    FIL *fp,            /* Pointer to the blank file object */
    const char *path,    /* Pointer to the file name */
    BYTE mode            /* Access mode and file open mode flags */
)返回结果是 FR_INVALID_NAME ,无效的文件名

跟踪发现,make_dirfile (            /* 1: error - detected an invalid format, '\0'or'/': next character */
    const char **path,        /* Pointer to the file path pointer */
    char *dirname            /* Pointer to directory name buffer {Name(8), Ext(3), NT flag(1)} */
)  内部判断时,认为“绿色.txt”是无效的文件名

/*-----------------------------------------------------------------------*/
/* Pick a paragraph and create the name in format of directory entry     */
/*-----------------------------------------------------------------------*/

static
char make_dirfile (            /* 1: error - detected an invalid format, '\0'or'/': next character */
    const char **path,        /* Pointer to the file path pointer */
    char *dirname            /* Pointer to directory name buffer {Name(8), Ext(3), NT flag(1)} */
)
{
    BYTE n, t, c, a, b;


    memset(dirname, ' ', 8+3);    /* Fill buffer with spaces */
    a = 0; b = 0x18;    /* NT flag */
    n = 0; t = 8;
    for (;;) {
        c = *(*path)++;
        if (c == '\0' || c == '/') {        /* Reached to end of str or directory separator */
            if (n == 0) break;
            dirname[11] = _USE_NTFLAG ? (a & b) : 0;
            return c;
        }
        if (c <= ' ' || c == 0x7F) break;        /* Reject invisible chars */
        if (c == '.') {
            if (!(a & 1) && n >= 1 && n <= 8) {    /* Enter extension part */
                n = 8; t = 11; continue;
            }
            break;
        }
        if (_USE_SJIS &&
            ((c >= 0x81 && c <= 0x9F) ||    /* Accept S-JIS code */
            (c >= 0xE0 && c <= 0xFC))) {
            if (n == 0 && c == 0xE5)        /* Change heading \xE5 to \x05 */
                c = 0x05;
            a ^= 1; goto md_l2;
        }
        if (c == '"') break;                /* Reject " */
        if (c <= ')') goto md_l1;            /* Accept ! # $ % & ' ( ) */
        if (c <= ',') break;                /* Reject * + , */
        if (c <= '9') goto md_l1;            /* Accept - 0-9 */
        if (c <= '?') break;                /* Reject : ; < = > ? */
        if (!(a & 1)) {    /* These checks are not applied to S-JIS 2nd byte */
            if (c == '|') break;            /* Reject | */
            if (c >= '[' && c <= ']') break;/* Reject [ \ ] */
            if (_USE_NTFLAG && c >= 'A' && c <= 'Z')
                (t == 8) ? (b &= ~0x08) : (b &= ~0x10);
            if (c >= 'a' && c <= 'z') {        /* Convert to upper case */
                c -= 0x20;
                if (_USE_NTFLAG) (t == 8) ? (a |= 0x08) : (a |= 0x10);
            }
        }
    md_l1:
        a &= ~1;
    md_l2:
        if (n >= t) break;
        dirname[n++] = c;
    }
    return 1;
}




请教各位熟悉 FAT 的朋友,文件名采用的是什么编码,是unicode吗?还是GB?还是其他?
如何才能让 FATFS 正确读取 文件名 为 中文 的文件?

出0入148汤圆

发表于 2009-9-4 10:14:50 | 显示全部楼层
需要打开长文件名支持,并且指定编码,但是会消耗大量的rom。

可以参考我翻译的一篇使用说明:http://www.openrtos.cn/ff007/appnote.html

出0入0汤圆

 楼主| 发表于 2009-9-4 11:07:20 | 显示全部楼层
谢谢楼上

提供的资料很有帮助,谢谢!

但是,仍有疑问,我的文件“绿色.txt”,没有超过8个字符,应该不需要 长文件名 的支持吧?

我现在看的FATFS版本是R0.04b ,可能没有提供 中文 的支持。我再去看看 0.07 的。

另外,其他的 文件系统, 例如uc/fs    elfs 等是不是同样也需要 编码 放在ROM里才能支持 中文  文件名 呢?

有没有什么变通的方法,可以正确读取 中文文件名 的文件呢。
我发现  中英文 或数字 混合 文件名,有些可以被认为文件名 合法。例如“12绿色ab.txt”是可以的。

出0入0汤圆

 楼主| 发表于 2009-9-4 11:11:56 | 显示全部楼层
现在对FATFS还不是很熟悉,正在学习代码。

如果不要对 文件名 进行 有效性 检查呢。会造成什么后果?能否通过简单的修改,让fatfs 支持中文文件名(小于8字符的短文件名)。
头像被屏蔽

出0入0汤圆

发表于 2009-9-4 11:33:05 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2009-9-4 12:54:38 | 显示全部楼层
FAT中8.3格式用的是GBK编码,LFN用的是Unicode编码。

出0入0汤圆

 楼主| 发表于 2009-9-4 15:35:18 | 显示全部楼层
谢谢

中文 编码 还真是麻烦啊,

正在想变通的方法

让FATFS忽略 8+3 的短 中文名 错误,

因为我现在的要求是:不需正确显示文件名,但要能正确打开文件,比如MP3,只要能播放;txt,只要能把内容读出。

出0入0汤圆

发表于 2009-9-6 13:13:32 | 显示全部楼层
收藏

出0入0汤圆

发表于 2009-9-6 14:11:09 | 显示全部楼层
学习了

出0入0汤圆

发表于 2009-9-6 17:17:17 | 显示全部楼层
看看

出0入0汤圆

发表于 2009-12-4 12:33:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-14 16:08:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-23 14:29:22 | 显示全部楼层
最新的R0.07e应该是支持的了,只要预定义#elif _CODE_PAGE == 936        /* Simplified Chinese GBK */。

出0入0汤圆

发表于 2009-12-23 14:50:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-20 15:43:39 | 显示全部楼层
回复【3楼】benfenshusheng
-----------------------------------------------------------------------

求助:FATfs 英文长文件名的问题:怎么才能不显示~1?
在STM32 上移植了一个FATFfs,但是在写长文件名后,在windows下读出保存的文件,文件名总是显示不全。
例如写的是“longname12345678901234567890.txt”
在windows下读SD卡,看到文件名是LONGNA~1TXT

出0入0汤圆

发表于 2010-7-20 16:53:39 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2010-8-16 16:17:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-18 15:32:43 | 显示全部楼层
回复【6楼】benfenshusheng
谢谢
中文 编码 还真是麻烦啊,
正在想变通的方法
让fatfs忽略 8+3 的短 中文名 错误,
因为我现在的要求是:不需正确显示文件名,但要能正确打开文件,比如mp3,只要能播放;txt,只要能把内容读出。
-----------------------------------------------------------------------

benfenshusheng,我正遇到相同的问题,请问,你是怎么解决的?

出0入0汤圆

发表于 2010-12-18 00:14:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-19 17:02:47 | 显示全部楼层
学习了

出0入0汤圆

发表于 2011-1-4 10:53:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-6 10:06:13 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-9-8 18:36:02 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-9-8 23:35:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-9 12:17:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-13 00:56:06 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-10-13 08:43:13 | 显示全部楼层
你可以这样设置:
#define _CODE_PAGE        437
#define        _USE_LFN        1                /* 大于0都可以 */
#define        _LFN_UNICODE        0        /* 0:ANSI/OEM or 1:Unicode */
你就会发现你可以使用长文件名,中文也可以,全是内码,不用转换

出0入0汤圆

发表于 2011-10-22 00:06:20 | 显示全部楼层
将  follow_path 函数中的 if ((UINT)*path < ' ') 改为
if ((unsigned char)(*path) < (unsigned char)' ') 即可
具体原因分析中。。。

/////////////////////////////////////////////////////////////////////////////////////
不用打开长文件名,code_page设为437,修改上述地方就可以第一个字用中文了。
跟了一下,发现if ((UINT)*path < ' ')是按有符号数比较的,大于0x80即为负数了,不知为啥。UINT明明是unsigned in。
我用的编译器是mcore编译器。不知在别的编译器上是不是也这样。

出0入0汤圆

发表于 2011-10-31 19:33:42 | 显示全部楼层
回复【26楼】amwox
-----------------------------------------------------------------------
你可以这样设置:
#define _CODE_PAGE 437
#define _USE_LFN 1 /* 大于0都可以 */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
你就会发现你可以使用长文件名,中文也可以,全是内码,不用转换


请问你用的是哪个版本的FATFS,我照你的方法试的不行啊

出0入0汤圆

发表于 2011-11-14 16:33:58 | 显示全部楼层
MARK!!

出0入0汤圆

发表于 2011-12-29 15:35:12 | 显示全部楼层
v

出0入0汤圆

发表于 2011-12-31 15:00:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-6-11 10:20:22 | 显示全部楼层
CC936.C那个文件实在是太大了,ROM不够

出0入0汤圆

发表于 2014-11-21 09:37:18 | 显示全部楼层
MARK        

出0入0汤圆

发表于 2014-11-21 09:40:17 | 显示全部楼层
把USE_LFN打开就行了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 05:52

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表