工作笔记1——利用bat脚本实现批量上传文件到ftp服务器
问题概述
公司中有大概225k个文件需要上传到某个ftp服务器特定的路径下,手动上传不太现实,所以需要写一个小工具实现自动上传。而且需要考虑到限速的问题,不能传太快导致服务器崩溃。在网上查找相关实现方法时,发现可以利用bat脚本完成,所以最后用该方法完成了这个任务,中间碰到了许多问题,在此记录一下。
利用ftp命令实现上传文件
//putfile.bat
echo open YOUR_FTP_SERVER >ftp.txt
echo user YOUR_USERNAME YOUR_USERPWD >>ftp.txt
echo cd YOUR_FTP_FILE_PATH >>ftp.txt
echo binary >>ftp.txt
echo lcd "YOUR_LOCAL_FILE_PATH" >>ftp.txt
echo put FILE_NAME >>ftp.txt
echo bye >>ftp.txt
FTP -n -s:ftp.txt YOUR_FTP_SERVER
del ftp.txt
注意
- 在写用户名和密码时,如果其中有特殊字符,需要记得处理,否则登录不上,例:我的密码中有&特殊字符,导致刚开始的时候一直连不上,后来发现是第二句话根本就没有写进ftp.txt文件中。解决办法:在&字符前加一个^即可
- YOUR_FTP_FILE_PATH:例 .\Test
- YOUR_LOCAL_FILE_PATH:例 D:\files\test
- put 命令表示一次上传一个文件,若想批量上传,则可用mput命令
限时功能
若想一次上传多个文件,则可用mput命令,但只要一使用该命令,则会不停上传文件,无法完成限时功能,所以想到循环调用put命令,并在每一次上传后通过ping 127.0.0.1 -n 2 命令来实现延时作用,该命令功能详解点此链接。
但是put命令需要指定需传送的文件名,而我们想要循环传送某一文件夹下的所有文件,说明该文件名是不固定的,所以我采用的方法是,通过两个bat文件,第一个bat文件将文件夹下的所有文件名写入某一txt文本中,然后循环调用第二个bat脚本,并将每一个文件名以参数传递进去,所以最后两个bat脚本如下:
//upload.bat
if not exist .\temp\filename.tmp (
::先将所有edi文件名写入filename.tmp临时文件中
dir /B %MAPDRIVE%:\*.edi > .\temp\filename.tmp
)
::调用putfile.bat,并以每一行的文件名为参数传递进去
for /f "tokens=1" %%i in (.\temp\filename.tmp) do (
call .\call_bats\putfile.bat %%i
)
//putfile.bat
::利用 %1 来获得传递进来的参数
echo open YOUR_FTP_SERVER >ftp.txt
echo user YOUR_USERNAME YOUR_USERPWD >>ftp.txt
echo Cd YOUR_FTP_FILE_PATH >>ftp.txt
echo binary >>ftp.txt
echo lcd "YOUR_LOCAL_FILE_PATH" >>ftp.txt
echo put %1 >>ftp.txt
echo bye >>ftp.txt
FTP -n -s:ftp.txt YOUR_FTP_SERVER
del ftp.txt
::利用ping命令延时,每传一个文件,停顿约1~2秒
ping 127.0.0.1 -n 2
)
- bat命令中for /f 的用法详见此链接。
将共享目录映射到电脑中的某个盘符
因为我的电脑只能通过网络邻居中的共享目录访问到公司中的这些文件,所以只能先将该共享目录映射到我的电脑中的某个盘上,然后才能进行访问。将共享目录映射到我的电脑中的某个盘上,需执行pushd SHARE_PATH 命令,之后又需获得映射到的那个盘符,所以整个过程如下:
//upload.bat
::保存当前执行路径
set BAT_FILE_PATH=%~DP0
SET MAPDRIVE=
if exist .\temp\mapdrivername.tmp (
for /f "tokens=1" %%i in (.\temp\mapdrivername.tmp) do set MAPDRIVE=%%i
)
if not exist .\temp\mapdrivername.tmp (
pushd %SHARE_DIR%
::找到映射盘符
CD | CHOICE /C:ABCDEFGHIJKLMNOPQRSTUVWXYZ > NUL
IF ERRORLEVEL 1 SET MAPDRIVE=A
IF ERRORLEVEL 2 SET MAPDRIVE=B
IF ERRORLEVEL 3 SET MAPDRIVE=C
IF ERRORLEVEL 4 SET MAPDRIVE=D
IF ERRORLEVEL 5 SET MAPDRIVE=E
IF ERRORLEVEL 6 SET MAPDRIVE=F
IF ERRORLEVEL 7 SET MAPDRIVE=G
IF ERRORLEVEL 8 SET MAPDRIVE=H
IF ERRORLEVEL 9 SET MAPDRIVE=I
IF ERRORLEVEL 10 SET MAPDRIVE=J
IF ERRORLEVEL 11 SET MAPDRIVE=K
IF ERRORLEVEL 12 SET MAPDRIVE=L
IF ERRORLEVEL 13 SET MAPDRIVE=M
IF ERRORLEVEL 14 SET MAPDRIVE=N
IF ERRORLEVEL 15 SET MAPDRIVE=O
IF ERRORLEVEL 16 SET MAPDRIVE=P
IF ERRORLEVEL 17 SET MAPDRIVE=Q
IF ERRORLEVEL 18 SET MAPDRIVE=R
IF ERRORLEVEL 19 SET MAPDRIVE=S
IF ERRORLEVEL 20 SET MAPDRIVE=T
IF ERRORLEVEL 21 SET MAPDRIVE=U
IF ERRORLEVEL 22 SET MAPDRIVE=V
IF ERRORLEVEL 23 SET MAPDRIVE=W
IF ERRORLEVEL 24 SET MAPDRIVE=X
IF ERRORLEVEL 25 SET MAPDRIVE=Y
IF ERRORLEVEL 26 SET MAPDRIVE=Z
)
::再回到当前执行目录
pushd %BAT_FILE_PATH%
echo %MAPDRIVE% >.\temp\mapdrivername.tmp
实现断点续传
因为文件数量过多,所以万一在传输过程中中断,则需能够实现已经上传过的文件不会再上传一次,它的实现思想可以为:将已传过的文件名保存下来,如果即将要传送的文件的文件名已经保存过,则跳过该文件,继续判断下一个;或者通过在本地备份一份,如果该文件已经存在,则不再上传。