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 15:47
回复【6楼】黑白边缘:
---------------------------------
我的F4综合实验,测试过。
黑白边缘
2楼-- · 2019-07-21 21:19
回复【7楼】正点原子:
---------------------------------
额,我找不出来错误在哪里了,起码上层的逻辑代码找不出来。估计得改策略了mf_copy函数的while(1)(就是一个文件读出再写入另一个文件)
改成如下:
while(1) {
f_lseek(&fsrc,fsrc.fptr+4096*i);
res = f_open( &fsrc, (const TCHAR *)psrc, FA_READ | FA_OPEN_EXISTING );
res = f_read(&fsrc, fbuf, 4096, (UINT*)&br); 
f_close(&fsrc);
        if(res || br == 0)
        {
          break;
        }

f_lseek(&fdst,fdst.fptr+4096*i);
res = f_open( &fdst, (const TCHAR *)pdst, FA_WRITE | fwmode );
res = f_write(&fdst, fbuf, (UINT)br, (UINT*)&bw); 
f_close(&fdst);
        if(res || br < 4096||bw < br)
        {
          break;
        }

i++;
}    
可以这样好没效率啊,我的FATFS可能出现问题了吗
正点原子
3楼-- · 2019-07-22 01:10
回复【8楼】黑白边缘:
---------------------------------
这个你再慢慢分析下吧,我也不知道了,呵呵。
黑白边缘
4楼-- · 2019-07-22 03:11
 精彩回答 2  元偷偷看……
黑白边缘
5楼-- · 2019-07-22 05:15
真是有心栽花花不发,无心插柳柳成荫

一周热门 更多>