文件夹复制代码用的原子哥的,稍微改动了一下:问题及代码呈上
[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天了愣是没发现错误,求指点
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
---------------------------------
我的F4综合实验,测试过。
---------------------------------
额,我找不出来错误在哪里了,起码上层的逻辑代码找不出来。估计得改策略了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可能出现问题了吗
---------------------------------
这个你再慢慢分析下吧,我也不知道了,呵呵。
一周热门 更多>