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之前说的文件夹复制有问题,可以参考一下我这个代码. |