FATFS Copy Files

  1 // 文件复制
  2 // 将psrc文件,copy到pdst.
  3 // psrc,pdst:源文件和目标文件
  4 // fwmode:文件写入模式
  5 // 0:不覆盖原有的文件
  6 // 1:覆盖原有的文件
  7 u8 mf_copy ( u8 * psrc, u8 * pdst, u8 fwmode )
  8 {
  9   u8 res;
 10   u16   br   = 0;
 11   u16   bw   = 0;
 12   FIL * fsrc = 0;
 13   FIL * fdst = 0;
 14   u8 *  fbuf = 0;
 15   fsrc       = ( FIL* )mymalloc ( SRAMIN, sizeof( FIL ) ); // 申请内存
 16   fdst       = ( FIL* )mymalloc ( SRAMIN, sizeof( FIL ) );
 17   fbuf       = ( u8* )mymalloc ( SRAMIN, 512 );
 18   if ( fsrc == NULL || fdst == NULL || fbuf == NULL )
 19   {
 20     res = 100;
 21   } // 前面的值留给fatfs
 22   else
 23   {
 24     if ( fwmode == 0 )
 25     {
 26       fwmode = FA_CREATE_NEW;
 27     } // 不覆盖
 28     else
 29     {
 30       fwmode = FA_CREATE_ALWAYS;
 31     } // 覆盖存在的文件
 32 
 33     res = f_open ( fsrc, ( const TCHAR * )psrc, FA_READ | FA_OPEN_EXISTING );
 34     // 打开只读文件
 35     if ( res == 0 )
 36     {
 37       res = f_open ( fdst, ( const TCHAR * )pdst, FA_WRITE | fwmode );
 38     }               // 第一个打开成功,才开始打开第二个
 39     if ( res == 0 ) // 两个都打开成功了
 40     {
 41       while ( res == 0 ) // 开始复制
 42       {
 43         res = f_read ( fsrc, fbuf, 512, ( UINT* )&br ); // 源头读出512字节
 44         if ( res || br == 0 )
 45         {
 46           break;
 47         }
 48         res = f_write ( fdst, fbuf, ( UINT )br, ( UINT* )&bw ); // 写入目的文件
 49         if ( res || bw < br )
 50         {
 51           break;
 52         }
 53       }
 54       f_close ( fsrc );
 55       f_close ( fdst );
 56     }
 57   }
 58   myfree ( SRAMIN, fsrc ); // 释放内存
 59   myfree ( SRAMIN, fdst );
 60   myfree ( SRAMIN, fbuf );
 61   return res;
 62 }
 63 
 64 // 得到路径下的文件夹
 65 // 返回值:0,路径就是个卷标号.
 66 // 其他,文件夹名字首地址
 67 u8 * get_src_dname ( u8 * dpfn )
 68 {
 69   u16 temp = 0;
 70   while ( *dpfn != 0 )
 71   {
 72     dpfn++;
 73     temp++;
 74   }
 75   if ( temp < 4 )
 76   {
 77     return 0;
 78   }
 79   while ( ( *dpfn != 0x5c ) && ( *dpfn != 0x2f ) )
 80   {
 81     dpfn--;
 82   } // 追述到倒数第一个"\"或者"/"处
 83   return++dpfn;
 84 }
 85 
 86 // 文件夹复制
 87 // 将psrc文件夹,copy到pdst文件夹.
 88 // pdst:必须形如"X:"/"X:XX"/"X:XX/XX"之类的.而且要实现确认上一级文件夹存在
 89 // psrc,pdst:源文件夹和目标文件夹
 90 // fwmode:文件写入模式
 91 // 0:不覆盖原有的文件
 92 // 1:覆盖原有的文件
 93 u8 mf_dcopy ( u8 * psrc, u8 * pdst, u8 fwmode )
 94 {
 95   #define MAX_PATHNAME_DEPTH 512+1 //最大目标文件路径+文件名深度
 96   u8        res    = 0;
 97   DIR *     srcdir = 0; // 源目录
 98   DIR *     dstdir = 0; // 源目录
 99   FILINFO * finfo  = 0; // 文件信息
100   u8 *      fn     = 0; // 长文件名
101 
102   u8 * dstpathname = 0; // 目标文件夹路径+文件名
103   u8 * srcpathname = 0; // 源文件夹路径+文件名
104 
105   u16 dstpathlen = 0; // 目标路径长度
106   u16 srcpathlen = 0; // 源路径长度
107 
108   srcdir = ( DIR* )mymalloc ( SRAMIN, sizeof( DIR ) ); // 申请内存
109   dstdir = ( DIR* )mymalloc ( SRAMIN, sizeof( DIR ) );
110   finfo  = ( FILINFO* )mymalloc ( SRAMIN, sizeof( FILINFO ) );
111 
112   if ( srcdir == NULL || dstdir == NULL || finfo == NULL )
113   {
114     res = 100;
115   }
116   if ( res == 0 )
117   {
118     finfo->lfsize = _MAX_LFN * 2 + 1;
119     finfo->lfname = mymalloc ( SRAMIN, finfo->lfsize ); // 申请内存
120     dstpathname   = mymalloc ( SRAMIN, MAX_PATHNAME_DEPTH );
121     srcpathname   = mymalloc ( SRAMIN, MAX_PATHNAME_DEPTH );
122     if ( finfo->lfname == NULL || dstpathname == NULL || srcpathname == NULL )
123     {
124       res = 101;
125     }
126     if ( res == 0 )
127     {
128       dstpathname[ 0 ] = 0;
129       srcpathname[ 0 ] = 0;
130       strcat ( ( char * )srcpathname, ( const char * )psrc ); // 复制原始源文件路径
131       strcat ( ( char * )dstpathname, ( const char * )pdst ); // 复制原始目标文件路径
132       res = f_opendir ( srcdir, ( const TCHAR * )psrc );      // 打开源目录
133       if ( res == 0 )                                         // 打开目录成功
134       {
135         strcat ( ( char * )dstpathname, ( const char * )"/" ); // 加入斜杠
136         fn = get_src_dname ( psrc );
137         if ( fn == 0 ) // 卷标拷贝
138         {
139           dstpathlen                = strlen ( ( const char * )dstpathname );
140           dstpathname[ dstpathlen ] = psrc[ 0 ]; // 记录卷标
141           dstpathname[ dstpathlen + 1 ] = 0;     // 结束符
142         }
143         else
144         {
145           strcat ( ( char * )dstpathname, ( const char * )fn );
146         } // 加文件名
147         res = f_mkdir ( ( const TCHAR * )dstpathname );
148         // 如果文件夹已经存在,就不创建.如果不存在就创建新的文件夹.
149         if ( res == FR_EXIST )
150         {
151           res = 0;
152         }
153         while ( res == 0 ) // 开始复制文件夹里面的东东
154         {
155           res = f_readdir ( srcdir, finfo ); // 读取目录下的一个文件
156           if ( res != FR_OK || finfo->fname[ 0 ] == 0 )
157           {
158             break;
159           } // 错误了/到末尾了,退出
160           if ( finfo->fname[ 0 ] == '.' )
161           {
162             continue;
163           } // 忽略上级目录
164           fn = ( u8* )( *finfo->lfname ? finfo->lfname : finfo->fname );
165           // 得到文件名
166           dstpathlen = strlen ( ( const char * )dstpathname ); // 得到当前目标路径的长度
167           srcpathlen = strlen ( ( const char * )srcpathname ); // 得到源路径长度
168 
169           strcat ( ( char * )srcpathname, ( const char * )"/" ); // 源路径加斜杠
170           if ( finfo->fattrib & 0X10 ) // 是子目录   文件属性,0X20,归档文件;0X10,子目录;
171           {
172             strcat ( ( char * )srcpathname, ( const char * )fn ); // 源路径加上子目录名字
173             printf ( "\r\ncopy folder %s to %s\r\n", srcpathname,
174               dstpathname );                                     // 拷贝文件
175             res = mf_dcopy ( srcpathname, dstpathname, fwmode ); // 拷贝文件夹
176           }
177           else // 非目录
178           {
179             strcat ( ( char * )dstpathname, ( const char * )"/" ); // 目标路径加斜杠
180             strcat ( ( char * )dstpathname, ( const char * )fn );  // 目标路径加文件名
181             strcat ( ( char * )srcpathname, ( const char * )fn );  // 源路径加文件名
182             printf ( "\r\ncopy file %s to %s\r\n", srcpathname,
183               dstpathname );                              // 拷贝文件
184             mf_copy ( srcpathname, dstpathname, fwmode ); // 复制文件
185           }
186           srcpathname[ srcpathlen ] = 0; // 加入结束符
187           dstpathname[ dstpathlen ] = 0; // 加入结束符
188         }
189       }
190       myfree ( SRAMIN, dstpathname );
191       myfree ( SRAMIN, srcpathname );
192       myfree ( SRAMIN, finfo->lfname );
193     }
194   }
195   myfree ( SRAMIN, srcdir );
196   myfree ( SRAMIN, dstdir );
197   myfree ( SRAMIN, finfo );
198   return res;
199 }

http://www.openedv.com/posts/list/6567.htm
刚刚完成了fatfs下面的文件夹复制,貌似没有问题,Traids之前说的文件夹复制有问题,可以参考一下我这个代码.


posted @ 2012-07-31 12:14  IAmAProgrammer  阅读(2592)  评论(0编辑  收藏  举报