从ftp服务器自动下载文件夹到本地

   最近有用到ftp文件传输协议从服务器端下载文件到本地,其中需要设计到bat实现ftp的自动登录,以及登录之后对ftp目录下特定文件夹进行遍历下载传输,并统计下载所需的时间。网上很多版本都是下载某一目录下面所有文件,并不能实现文件夹的递归遍历。另外比较普遍的处理方案是将所有需要备份的文件夹进行压缩,在特定时间将该压缩包网络传输备份(多用于定时备份服务器端日志文件)。
   考虑到特殊的需要,这里实现上述功能。并将使用到的源码解析如下:

   ftp自动登录脚本auto.bat,运行后会将ftp服务器端的pxe目录下面的所有文件下载到本地C:/temp目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
rem filename : auto.bat
rem function : auto login in and download from ftp://efi_testing:Pass_123@192.168.12.10/pxe to c:/temp

@echo off

rem 指定FTP用户名
set ftpUser='efi_testing'
rem 指定FTP密码
set ftpPass='Pass_123'
rem 指定FTP服务器地址
set ftpIP=192.168.12.10
rem 指定待下载的文件位于FTP服务器的哪个目录
set ftpFolder=/pxe
rem 指定从FTP下载下来的文件存放到本机哪个目录
set LocalFolder=C:/temp

echo open %ftpIP% >> ftp.txt
echo cd "%ftpFolder%" >> ftp.txt
echo lcd "%LocalFolder%" >>ftp.txt
echo mget *.* >> ftp.txt
echo bye >>ftp.txt
ftp -i -n -s:ftp.txt //易出错,注意
pause

   其中ftp语法如下:

1
2
3
4
5
6
7
8
9
10
11
12
ftp [-v] [-d] [-i] [-n] [-g] [-s:FileName] [-a] [-w:WindowSize] [-A] [Host]
参数:
-v:禁止显示远程服务器响应。
-d:启用调试、显示在客户端和服务器之间传递的所有ftp命令。
-i:多个文件传送时关闭交互提示。
-n:禁止自动登录到初始连接。
-g:禁用文件名组,它允许在本地文件和路径名中使用通配符字符(*和?)。
-s:FileName:指定包含ftp命令的文本文件;当ftp启动后,这些命令将自动运行。该参数中不允许有空格。使用该开关而不是重定向(>)。
-a:在捆绑数据连接时使用任何本地接口。
-w:WindowSize:替代默认大小为4096的传送缓冲区。
-A:匿名登陆。
Host:指定要连接到远程计算机的计算机名或IP地址。如果指定,计算机必须是最后一个参数。

   ftpget.bat文件,在这个文件中完成ftp自动登录和ftp下载文件到本地功能,并统计出所需时间(时:分:秒)。其中会调用下面maketree.bat脚本,生成遍历后的文件夹递归目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
rem filename: ftpget.bat
rem function: auto login in and download from ftp://efi_testing:Pass_123@192.168.12.10/client to %cd%

@echo off

set host=192.168.12.10
set user=efi_testing
set pass=Pass_123
set dirname=client
set homedir=%cd%

rem 生成FTP目录结构
if exist tree.txt del tree.txt

set time_begin=%time:~0,-3%
start /w cmd /c makeTree %dirname% 0
del result*.txt

for /f "delims=/" %%i in (tree.txt) do (

rem 获取dirname的所有文件
rem =============================
cd %homedir%
md %%i
cd /d %%i

echo open %host%>ftp.txt
echo user %user% %pass%>>ftp.txt
echo cd %%i>>ftp.txt

rem mget *.* 下载所有文件,但不能下载无扩展名的文件;
rem 如果使用mget * 可以下载所有文件,但会把子目录的文件也下载过来
echo mget *.*>>ftp.txt

echo bye>>ftp.txt
ftp -i -n -s:ftp.txt
del ftp.txt
rem ==============================

)
cd %homedir%
del tree.txt

set time_end=%time:~0,-3%
call :time_lapse
echo All copy cost %hour_% hours %munite_% minutes %second_% seconds
pause>nul
goto :eof


:time_lapse
:: 一定要按照 秒=>分钟=>小时 的顺序操作

for /f "tokens=1,2,3 delims=:" %%i in ("%time_begin%") do (
set /a hour_b=%%i
set /a munite_b=%%j
set /a second_b=%%k
)

for /f "tokens=1,2,3 delims=:" %%i in ("%time_end%") do (
set /a hour_e=%%i
set /a munite_e=%%j
set /a second_e=%%k
)

if %second_e% lss %second_b% (
set /a munite_e=%munite_e%-1
set /a second_e=%second_e%+60
)
set /a second_=%second_e%-%second_b%
if %munite_e% lss %munite_b% (
set /a hour_e=%hour_e%-1
set /a munite_e=%munite_e%+60
)
set /a munite_=%munite_e%-%munite_b%
if %hour_e% lss %hour_b% (
set /a hour_e=%hour_e%+24
)
set /a hour_=%hour_e%-%hour_b%
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
rem filename:  maketree.bat
rem function: generate ftp directory structure
rem 调用方法 maketree dir1\dir2 n (n>=1)
rem %1 == dir1\dir2
rem %2 == n
@echo off

set /a treetime=%2+1
echo %1 >>tree.txt

echo open %host% > ftp%treetime%.txt
echo user %user% %pass% >>ftp%treetime%.txt
echo cd %1 >>ftp%treetime%.txt

echo dir >>ftp%treetime%.txt
echo bye >>ftp%treetime%.txt

ftp -i -n -s:ftp%treetime%.txt |find "<DIR>">result%treetime%.txt
for /f "tokens=2,3*" %%i in (result%treetime%.txt) do (start /w cmd /c Maketree.bat %1\%%k %treetime%)
rem del result%treetime%.txt
rem del ftp%treetime%.txt

   不积跬步,无以至千里;不积小流,无以成江海。每天进步一点点。