jsdn2000 发表于 2017-1-20 09:02:31

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

zhuyl369 发表于 2017-1-21 09:33:05

如果FTP目录你有删除权限,我觉得你可以执行DOS命令"RD /S /Q FTPpath "来删除非空目录

jsdn2000 发表于 2017-1-21 18:16:40

2楼的朋友,我指的是删除ftp远程文件夹的非空文件夹,你说的是本地的dos命令。

tubaba 发表于 2017-1-21 19:20:55

这个问题我去年遇到过,采取的方法是列出Ftp文件夹的文件目录列表数组,最深的文件放在最后,然后根据数组,由后向前进行删除

jsdn2000 发表于 2017-1-22 10:02:22

谢谢楼上的指点思路,我的最初的思路也是如此:
1、先循环删除远程ftp的非空文件夹中的所有文件,这一点相对容易做到;
2、把ftp非空文件夹下面的所有文件夹路径存入数组列表,然后从最后向最前删除。
调试的时候遇到了一些问题,所以才在网络上搜索,找到了这个UDF,也一直没有调试成功。
还是安装当初的思路,重新调试吧,调试成功的话贴上源码。

jsdn2000 发表于 2017-1-22 10:04:10

回复 4# tubaba

还有一个问题请教一下三楼的朋友,判断FTP非空文件夹的层数有什么好的办法吗?

tubaba 发表于 2017-1-22 13:24:37

回复 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

jsdn2000 发表于 2017-1-22 15:47:38

感谢tubaba兄的热情帮助,快过年了,抓紧时间处理手头的事情,下班时间来调试一下程序,需要点时间来消化一下。这个问题已经纠结两个星期了,再次表示感谢。
页: [1]
查看完整版本: FTP删除非空文件夹遇到的问题,请教各位[已解决]