找回密码
 加入
搜索
查看: 2512|回复: 7

[网络通信] FTP删除非空文件夹遇到的问题,请教各位[已解决]

[复制链接]
发表于 2017-1-20 09:02:31 | 显示全部楼层 |阅读模式
本帖最后由 jsdn2000 于 2017-2-8 11:09 编辑

自己在写某个功能的时候需要删除远程FTP文件夹的一个目录树,是非空文件夹,ftp的UDF里面自带的命令_FTP_DirDelete只能删除空文件夹,自己在ACN和AU3官方论坛搜索也只能搜索到以下这一个UDF,但是对于这个UDF调试过程中,发现后一部分始终处于死循环,怀疑是$sFolderlist &= $sWorkingdir & "/" & $aFile[10] & ';  这一行代码经调试,在循环读到最深一层文件夹的时候,不能返回上一层文件夹而造成死循环。   类似于  "/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[2] = [1, $sFTPDirectory]
    While $aFolderStack[0] > 0
        $sWorkingdir = $aFolderStack[$aFolderStack[0]]
        $aFolderStack[0] -= 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[1] = 16 Then; If file is a directory we are going to add it to the stack of folders we need to go through
                    $aFolderStack[0] += 1
                    If UBound($aFolderStack) <= $aFolderStack[0] Then ReDim $aFolderStack[UBound($aFolderStack) * 2]
                    $aFolderStack[$aFolderStack[0]] = $sWorkingdir & "/" & $aFile[10]
                    $sFolderlist &= $sWorkingdir & "/" & $aFile[10] & ';'; 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[10])
                    ConsoleWrite('File: ' & $sWorkingdir & "/" & $aFile[10] & ' Deleted' & @CRLF)
                EndIf
                $bFirst = False
            WEnd
        EndIf
        _FTP_FindFileClose($hSearch)
    WEnd
    $aFolderStack = StringSplit(StringTrimRight($sFolderlist, 1), ';')
    For $i = $aFolderStack[0] 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
发表于 2017-1-21 09:33:05 | 显示全部楼层
如果FTP目录你有删除权限,我觉得你可以执行DOS命令"RD /S /Q FTPpath "来删除非空目录
 楼主| 发表于 2017-1-21 18:16:40 | 显示全部楼层
2楼的朋友,我指的是删除ftp远程文件夹的非空文件夹,你说的是本地的dos命令。
发表于 2017-1-21 19:20:55 | 显示全部楼层
这个问题我去年遇到过,采取的方法是列出Ftp文件夹的文件目录列表数组,最深的文件放在最后,然后根据数组,由后向前进行删除
 楼主| 发表于 2017-1-22 10:02:22 | 显示全部楼层
谢谢楼上的指点思路,我的最初的思路也是如此:
1、先循环删除远程ftp的非空文件夹中的所有文件,这一点相对容易做到;
2、把ftp非空文件夹下面的所有文件夹路径存入数组列表,然后从最后向最前删除。
调试的时候遇到了一些问题,所以才在网络上搜索,找到了这个UDF,也一直没有调试成功。
还是安装当初的思路,重新调试吧,调试成功的话贴上源码。
 楼主| 发表于 2017-1-22 10:04:10 | 显示全部楼层
回复 4# tubaba

还有一个问题请教一下三楼的朋友,判断FTP非空文件夹的层数有什么好的办法吗?
发表于 2017-1-22 13:24:37 | 显示全部楼层
回复 6# jsdn2000


    使用递归的方法列出文件目录
Func _FTP_DelTree($Conn, $Dir);这个函数给你参考一下
        Local $aList[1][1]
        _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][6] & '/' & $aList[$I][0] & '"', False, False, '总进度:' & ($aList[0][0] + 1 - $I) & '/' & $aList[0][0] & @CRLF & Chr(32) & Round(($aList[0][0] + 1 - $I) * 100 / $aList[0][0], 2) & '%')
                GUICtrlSetData($progressbar2, (($aList[0][0] + 1 - $I) * 100 / $aList[0][0]))
                Switch $aList[$I][2]
                        Case '16'
                                If Not _FTP_DirDelete($Conn, $aList[$I][6] & '/' & $aList[$I][0]) Then
                                        _WaitMessage('删除FTP上的目录: "' & $aList[$I][6] & '/' & $aList[$I][0] & '"失败')
                                        _Log('删除FTP上的目录: "' & $aList[$I][6] & '/' & $aList[$I][0] & '"失败,(可能原因①目录非空,存在隐藏文件,而域管理员设置了不显示隐藏文件,无法列出完整FTP文件列表.②目录设定了不能删除的保护性操作.③有其它用户正在操作此FTP.④文件夹的索引损坏.⑤文件夹名乱码或有空格,用ftp重命名该文件然后删除)')
                                        $finishflag = False
                                        Return SetError(1, 0, False)
                                EndIf
                        Case '128'
                                If Not _FTP_FileDelete($Conn, $aList[$I][6] & '/' & $aList[$I][0]) Then
                                        _WaitMessage('删除FTP上的文件: "' & $aList[$I][6] & '/' & $aList[$I][0] & '"失败')
                                        _Log('删除FTP上的文件: "' & $aList[$I][6] & '/' & $aList[$I][0] & '"失败,(可能原因①文件被锁定.②上层目录设定了不能写入的保护性操作.③有其它用户正在操作此文件.④文件的索引损坏.⑤文件名乱码或有空格,用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[0][0] + 1][UBound($aArray, 2)]
;~         _ArrayDisplay($aArray,'Debug~~~')
EndFunc   ;==>_FtpFilelistEx

Func __FtpFilelist(ByRef $aArray, $Conn, $searchdir);这个你可以照搬
        Local $iStep = 40000
        If $aArray[0][0] == '' Then $aArray[0][0] = 0
        _FTP_DirSetCurrent($Conn, $searchdir)
        Local $aFile = _FTP_ListToArrayEx($Conn, 0)
        If UBound($aArray, 1) <= $aArray[0][0] + 1 Then
                If UBound($aFile, 1) <= $iStep Then
                        ReDim $aArray[UBound($aArray, 1) + $iStep][UBound($aFile, 2) + 1]
                Else
                        ReDim $aArray[UBound($aArray, 1) + UBound($aFile, 1)][UBound($aFile, 2) + 1]
                EndIf
        EndIf
        Local $DirFound = 0, $CurrentDir = _FTP_DirGetCurrent($Conn)
        For $I = 1 To UBound($aFile, 1) - 1
                If ($aFile[$I][0] == '.') Or ($aFile[$I][0] == '..') Then ContinueLoop
                For $J = 0 To UBound($aFile, 2) - 1
                        $aArray[$aArray[0][0] + 1][$J] = $aFile[$I][$J]
                Next
                $aArray[$aArray[0][0] + 1][UBound($aFile, 2)] = $CurrentDir
                $aArray[0][0] += 1
                If $aFile[$I][2] == '16' Then ;是文件夹
                        $DirFound += 1
                        __FtpFilelist($aArray, $Conn, $CurrentDir & '/' & $aFile[$I][0])
                EndIf
        Next

        If $DirFound = 0 Then Return
EndFunc   ;==>__FtpFilelist
 楼主| 发表于 2017-1-22 15:47:38 | 显示全部楼层
感谢tubaba兄的热情帮助,快过年了,抓紧时间处理手头的事情,下班时间来调试一下程序,需要点时间来消化一下。这个问题已经纠结两个星期了,再次表示感谢。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-3-29 15:09 , Processed in 0.073928 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表