ST32F429,关于FATFS文件系统复制文件夹中,打开文件出现FR_TOO_MANY_OPEN_FILES的错误。

2019-07-21 04:23发布

文件夹复制代码用的原子哥的,稍微改动了一下:问题及代码呈上
[mw_shl_code=c,true]/************************************************************************** // 文件复制,将源文件夹复制到目标文件夹 // 将psrc文件,copy到pdst. // psrc,pdst:源文件和目标文件 // fwmode:文件写入模式 // 0:不覆盖原有的文件 // 1:覆盖原有的文件 ***************************************************************************/ FRESULT mf_copy(uint8_t* psrc, uint8_t* pdst, uint8_t fwmode ) { FRESULT res; uint16_t br = 0; uint16_t bw = 0; FIL fsrc,fdst; uint8_t fbuf[512] = {0}; if(fbuf == NULL) { res = 100; } else { if(fwmode == 0) { fwmode = FA_CREATE_NEW; } else { fwmode = FA_CREATE_ALWAYS; } res = f_open( &fsrc, (const TCHAR *)psrc, FA_READ | FA_OPEN_EXISTING ); //打开只读文件 if(res == 0) { res = f_open( &fdst, (const TCHAR *)pdst, FA_WRITE | fwmode ); //打开第一个再打开第二个 } if(res == 0) //2个都打开了 { while(res == 0) //开始复制 { res = f_read(&fsrc, fbuf, 512, (UINT*)&br); //从源文件读出512字节 if(res || br == 0) { break; } res = f_write(&fdst, fbuf, (UINT)br, (UINT*)&bw); // 写入目的文件 if(res || bw < br) { break; } } f_close(&fsrc); f_close(&fdst); } } free(fbuf); return res; } /********************************************************** *得到路径下的文件夹 返回值:卷标号或者文件夹的首地址 ***********************************************************/ uint8_t *get_src_dname(uint8_t* dpfn) { uint16_t temp = 0; while(*dpfn != 0) { dpfn++; temp++; } if(temp < 1) { return &dpfn[0]; //卷标名,不带“/” } while((*dpfn != 0x3a)&&(*dpfn != 0x2f)) //追述到倒数第一个“/”或者“:”处 { dpfn--; } return ++dpfn; } /***************************************************************** *pdst:必须形如“1:doc/file/abc.txt” ******************************************************************/ FRESULT mf_dcopy(uint8_t* psrc, uint8_t* pdst, uint8_t fwmode) { #define MAX_PATHNAME_DEPTH 512+1 //最大文件路径+文件名深度 FRESULT res = 0; uint8_t dstarray[MAX_PATHNAME_DEPTH] = {0},srcarray[MAX_PATHNAME_DEPTH] = {0}; DIR* srcdir = NULL; //源目录 DIR* dstdir = NULL; //目标目录 FILINFO* finfo = NULL; //文件信息 uint8_t* fn = NULL; //长文件名 uint8_t* dstpathname = dstarray; //??±ê???????·??(+??????) uint8_t* srcpathname = srcarray; //?????????·??(+??????) uint16_t dstpathlen = 0; //目标文件夹路径 uint16_t srcpathlen = 0; //源文件夹路径 srcdir = (DIR*)malloc(sizeof(DIR)); dstdir = (DIR*)malloc(sizeof(DIR)); finfo = (FILINFO*)malloc(sizeof(FILINFO)); if(srcdir == NULL || dstdir==NULL || finfo == NULL) { res = 100; } if(res == 0) { finfo->lfsize = _MAX_LFN*2 + 1; //Size of LFN buffer in TCHAR finfo->lfname = malloc(finfo->lfsize); //Pointer to the LFN buffer if(finfo->lfname == NULL) { res = 101; } if (res == 0) { strcat((char*)srcpathname, (const char*)psrc); //复制原始源文件(夹)路径 strcat((char*)dstpathname, (const char*)pdst); //复制目标文件(夹)路径 res = f_opendir (srcdir, (const TCHAR *)psrc); //打开源目录 if(res == 0) //打开成功 { strcat((char*)dstpathname, (const char*)"/" ); // 加入斜杠 fn = get_src_dname(psrc); //得到文件夹名字 if(fn == 0) //卷标拷贝 { dstpathlen = strlen((const char*)dstpathname); dstpathname[dstpathlen] = psrc[0]; dstpathname[dstpathlen + 1] = 0; } else { strcat((char*)dstpathname,(const char*)fn); //加文件名 } res = f_mkdir((const TCHAR*)dstpathname); //文件存在则打开,不存在就创建 if(res == FR_EXIST) { res = 0; } while(res == 0) //开始复制文件夹里的东西 { res = f_readdir(srcdir, finfo); //遍历文件夹 if(res != FR_OK || finfo->fname[ 0 ] == 0) //到了末尾了 { break; } fn = ( uint8_t* )( *finfo->lfname ? finfo->lfname : finfo->fname ); //得到文件名 dstpathlen = strlen(( const char * )dstpathname); //得到目标路径长度 srcpathlen = strlen(( const char * )srcpathname); //得到源路径长度 strcat((char *)srcpathname, (const char *)"/" ); if ( finfo->fattrib & 0X10 ) //为子目录,0x10子目录,0x20归档文件 { strcat((char *)srcpathname, (const char *)fn ); //源路径加子目录名字 res = mf_dcopy(srcpathname, dstpathname, fwmode); //调用自己 } else //非目录 { strcat((char *)dstpathname, (const char *)"/" ); //目标路径加'/' strcat((char *)dstpathname, (const char *)fn ); //目标路径加文件名 strcat((char *)srcpathname, (const char *)fn ); //源路径加文件名 mf_copy(srcpathname, dstpathname, fwmode); //拷贝文件 } srcpathname[srcpathlen] = 0; //加结束符 dstpathname[dstpathlen] = 0; //加结束符 } } free(finfo->lfname); } } free(srcdir); free(dstdir); free(finfo ); return res; } [/mw_shl_code]
主函数:
void main(void) {
.......
.......
uint8_t *psrc = "1:src",*pdst = "0:dst";    //1:SD卡的逻辑磁盘号,0:U盘的逻辑号

uint8_t fwmode = FA_CREATE_ALWAYS;

mf_dcopy(psrc, pdst, fwmode);

while(1);
}

用的FATFS文件系统
SD卡有文件夹src,src下有文件夹file、文件1.txt、2.txt;  file文件夹里有01.txt
U盘里有空文件夹dst

问题现象:

执行到第38行代码出现FR_TOO_MANY_OPEN_FILES的错误。即res = f_open( &fdst, (const TCHAR *)pdst, FA_WRITE | fwmode );

pdst路径是全路径,0:dst/src/file/01.txt,U盘之前也没有打开其他文件,只是再SD卡中接连打开了 src ,file文件而已
搞了1天了愣是没发现错误,求指点


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
黑白边缘
1楼-- · 2019-07-21 04:51
 精彩回答 2  元偷偷看……
黑白边缘
2楼-- · 2019-07-21 04:56
发现在  res = f_readdir(srcdir, finfo);读目录后,单独打开SD卡内文件可以,单独打开U盘文件也可以;但是同时打开SD卡和U盘就会FR_TOO_MANY_OPEN_FILES。SD卡和U盘貌似不相干啊,为什么会这样呢??
正点原子
3楼-- · 2019-07-21 09:22
同时打开SD和U盘的文件是不应该有问题才对的。
我们探索者F4开发板就可以边放SD卡的歌曲,边放U盘的图片的。
黑白边缘
4楼-- · 2019-07-21 11:08
我也觉得当进入一个目录,同时打开SD卡,和U盘的各一个文件不应该有问题的,但是抛开上面的文件夹复制代码,只是简单的做个测试:进入一个目录,同时打开SD卡,和U盘的各一个文件;它却报错了,感觉FATFS文件系统不应该如此脆弱啊
黑白边缘
5楼-- · 2019-07-21 12:07
 精彩回答 2  元偷偷看……
黑白边缘
6楼-- · 2019-07-21 12:19
回复【3楼】正点原子:
---------------------------------
原子哥你说的仅仅是同时打开SD卡,和U盘的各一个文件没有问题的吗,还是进入某个目录再打开?
我的是进入一个目录,再同时打开SD卡,和U盘的各一个文件出现FR_TOO_MANY_OPEN_FILES错误的。

一周热门 更多>