FTP删除非空文件夹遇到的问题,请教各位[已解决]
本帖最后由 jsdn2000 于 2017-2-8 11:09 编辑自己在写某个功能的时候需要删除远程FTP文件夹的一个目录树,是非空文件夹,ftp的UDF里面自带的命令_FTP_DirDelete只能删除空文件夹,自己在ACN和AU3官方论坛搜索也只能搜索到以下这一个UDF,但是对于这个UDF调试过程中,发现后一部分始终处于死循环,怀疑是$sFolderlist &= $sWorkingdir & "/" & $aFile & ';这一行代码经调试,在循环读到最深一层文件夹的时候,不能返回上一层文件夹而造成死循环。 类似于"/startdir/4/****/newfolder/../newfolder这样,造成以后的代码_Ftp_DirDelete不能从尾部到开始删除空文件夹,这个问题已经纠结了接近一星期了,还是没有调试好,麻烦各位帮助了,不知道自己描述的清楚否。
#include <FTPEx.au3>
#include <Array.au3>
$dir = '/4'
$server = '172.21.16.46'
$username = 'wwxsawis'
$pass = 'awis123'
$Open = _FTP_Open('test')
$Conn = _FTP_Connect($Open, $server, $username, $pass)
If Not @error Then ConsoleWrite('Connected!' & @CRLF)
_FTP_DirSetCurrent($Conn, '/StartDir/');Very Important to set the current dirctory to the directory that the folder you want to delete is in.
_FTPRemovedir($Conn, $dir)
_FTP_Close($Open)
Func _FTPRemovedir($l_FTPSession, $sFTPDirectory)
Local $aFile, $hSearch, $sWorkingdir, $sFolderlist, $i, $bFirst, $aFolderStack =
While $aFolderStack > 0
$sWorkingdir = $aFolderStack[$aFolderStack]
$aFolderStack -= 1
$aFile = _FTP_FindFileFirst($l_FTPSession, $sWorkingdir & '/*', $hSearch, $INTERNET_FLAG_NO_CACHE_WRITE)
If Not @error Then
$bFirst = True
While 1
If $bFirst = False Then
$aFile = _FTP_FindFileNext($hSearch)
If @error Then ExitLoop
EndIf
If $aFile = 16 Then; If file is a directory we are going to add it to the stack of folders we need to go through
$aFolderStack += 1
If UBound($aFolderStack) <= $aFolderStack Then ReDim $aFolderStack
$aFolderStack[$aFolderStack] = $sWorkingdir & "/" & $aFile
$sFolderlist &= $sWorkingdir & "/" & $aFile & ';'; Here I am adding the folder to a list of directorys I need to delete later
Else; else we delete it
_FTP_FileDelete($l_FTPSession, $sWorkingdir & "/" & $aFile)
ConsoleWrite('File: ' & $sWorkingdir & "/" & $aFile & ' Deleted' & @CRLF)
EndIf
$bFirst = False
WEnd
EndIf
_FTP_FindFileClose($hSearch)
WEnd
$aFolderStack = StringSplit(StringTrimRight($sFolderlist, 1), ';')
For $i = $aFolderStack To 1 Step -1 ;Here we delete all those empty folders from last to first
_FTP_DirDelete($l_FTPSession, $aFolderStack[$i])
ConsoleWrite('Directory: ' & $aFolderStack[$i] & ' Deleted' & @CRLF)
Next
_FTP_DirDelete($l_FTPSession, $sFTPDirectory);Delete the original directory
EndFunc ;==>_FTPRemovedir
如果FTP目录你有删除权限,我觉得你可以执行DOS命令"RD /S /Q FTPpath "来删除非空目录 2楼的朋友,我指的是删除ftp远程文件夹的非空文件夹,你说的是本地的dos命令。 这个问题我去年遇到过,采取的方法是列出Ftp文件夹的文件目录列表数组,最深的文件放在最后,然后根据数组,由后向前进行删除 谢谢楼上的指点思路,我的最初的思路也是如此:
1、先循环删除远程ftp的非空文件夹中的所有文件,这一点相对容易做到;
2、把ftp非空文件夹下面的所有文件夹路径存入数组列表,然后从最后向最前删除。
调试的时候遇到了一些问题,所以才在网络上搜索,找到了这个UDF,也一直没有调试成功。
还是安装当初的思路,重新调试吧,调试成功的话贴上源码。 回复 4# tubaba
还有一个问题请教一下三楼的朋友,判断FTP非空文件夹的层数有什么好的办法吗? 回复 6# jsdn2000
使用递归的方法列出文件目录
Func _FTP_DelTree($Conn, $Dir);这个函数给你参考一下
Local $aList
_FtpFilelistEx($aList, $Conn, $Dir)
_WaitMessage('正在删除旧的备份目录: ' & $Dir)
GUICtrlSetState($label4, $GUI_SHOW)
GUICtrlSetState($progressbar2, $GUI_SHOW)
For $I = UBound($aList) - 1 To 1 Step -1
_WaitMessage('正在删除 "' & $aList[$I] & '/' & $aList[$I] & '"', False, False, '总进度:' & ($aList + 1 - $I) & '/' & $aList & @CRLF & Chr(32) & Round(($aList + 1 - $I) * 100 / $aList, 2) & '%')
GUICtrlSetData($progressbar2, (($aList + 1 - $I) * 100 / $aList))
Switch $aList[$I]
Case '16'
If Not _FTP_DirDelete($Conn, $aList[$I] & '/' & $aList[$I]) Then
_WaitMessage('删除FTP上的目录: "' & $aList[$I] & '/' & $aList[$I] & '"失败')
_Log('删除FTP上的目录: "' & $aList[$I] & '/' & $aList[$I] & '"失败,(可能原因①目录非空,存在隐藏文件,而域管理员设置了不显示隐藏文件,无法列出完整FTP文件列表.②目录设定了不能删除的保护性操作.③有其它用户正在操作此FTP.④文件夹的索引损坏.⑤文件夹名乱码或有空格,用ftp重命名该文件然后删除)')
$finishflag = False
Return SetError(1, 0, False)
EndIf
Case '128'
If Not _FTP_FileDelete($Conn, $aList[$I] & '/' & $aList[$I]) Then
_WaitMessage('删除FTP上的文件: "' & $aList[$I] & '/' & $aList[$I] & '"失败')
_Log('删除FTP上的文件: "' & $aList[$I] & '/' & $aList[$I] & '"失败,(可能原因①文件被锁定.②上层目录设定了不能写入的保护性操作.③有其它用户正在操作此文件.④文件的索引损坏.⑤文件名乱码或有空格,用ftp重命名该文件然后删除)')
$finishflag = False
Return SetError(2, 0, False)
EndIf
EndSwitch
Next
If Not _FTP_DirDelete($Conn, $Dir) Then
_WaitMessage('删除FTP上的目录: "' & $Dir & '"失败')
_Log('删除FTP上的目录: "' & $Dir & '"失败')
$finishflag = False
Return SetError(3, 0, False)
EndIf
_WaitMessage('', False, False)
Return SetError(0, 0, True)
EndFunc ;==>_FTP_DelTree
Func _FtpFilelistEx(ByRef $aArray, $Conn, $searchdir);这个你可以照搬
__FtpFilelist($aArray, $Conn, $searchdir)
ReDim $aArray[$aArray + 1]
;~ _ArrayDisplay($aArray,'Debug~~~')
EndFunc ;==>_FtpFilelistEx
Func __FtpFilelist(ByRef $aArray, $Conn, $searchdir);这个你可以照搬
Local $iStep = 40000
If $aArray == '' Then $aArray = 0
_FTP_DirSetCurrent($Conn, $searchdir)
Local $aFile = _FTP_ListToArrayEx($Conn, 0)
If UBound($aArray, 1) <= $aArray + 1 Then
If UBound($aFile, 1) <= $iStep Then
ReDim $aArray
Else
ReDim $aArray
EndIf
EndIf
Local $DirFound = 0, $CurrentDir = _FTP_DirGetCurrent($Conn)
For $I = 1 To UBound($aFile, 1) - 1
If ($aFile[$I] == '.') Or ($aFile[$I] == '..') Then ContinueLoop
For $J = 0 To UBound($aFile, 2) - 1
$aArray[$aArray + 1][$J] = $aFile[$I][$J]
Next
$aArray[$aArray + 1] = $CurrentDir
$aArray += 1
If $aFile[$I] == '16' Then ;是文件夹
$DirFound += 1
__FtpFilelist($aArray, $Conn, $CurrentDir & '/' & $aFile[$I])
EndIf
Next
If $DirFound = 0 Then Return
EndFunc ;==>__FtpFilelist
感谢tubaba兄的热情帮助,快过年了,抓紧时间处理手头的事情,下班时间来调试一下程序,需要点时间来消化一下。这个问题已经纠结两个星期了,再次表示感谢。
页:
[1]