Actionscript 3 列出大量的文件和目录,包括AdobeAIR中的子目录

Actionscript 3 列出大量的文件和目录,包括AdobeAIR中的子目录,actionscript-3,apache-flex,air,filesystems,Actionscript 3,Apache Flex,Air,Filesystems,我正在尝试列出文件和目录,并将所有现有文件复制到任何其他文件夹中 顺便说一下,有许多文件和目录超过10万个以上 下面是代码的一部分 private function getFileList(sourceDir:String):void{ var file:File = File.userDirectory.resolvePath(sourceDir); file.addEventListener(FileListEvent.DIRECTORY_LISTING, directory

我正在尝试列出文件和目录,并将所有现有文件复制到任何其他文件夹中

顺便说一下,有许多文件和目录超过10万个以上

下面是代码的一部分

private function getFileList(sourceDir:String):void{
    var file:File = File.userDirectory.resolvePath(sourceDir);
    file.addEventListener(FileListEvent.DIRECTORY_LISTING, directory_listing);
    file.getDirectoryListingAsync();
}
private function directory_listing(e:FileListEvent):void{
    var getfiles:Array = e.files;

    for each(var item:File in e.files){

        if(checkDir(item.nativePath)){
            // It is a directory, more logic!
            totalDirNum++;
            item.addEventListener(FileListEvent.DIRECTORY_LISTING, directory_listing);
            item.getDirectoryListingAsync();
        }
        else{
        // It is a file, more logic!
            totalFileNum++;
                if(analyzeFile(item) === true){
                if(overwriteChk.selected === false){ // Don't overwrite same file
                            if(checkFile(destinationDir.nativePath + "\\" + item.name) === false){
                            copyInto(item, destinationDir.resolvePath(destinationDir.nativePath + "\\" + item.name));
                            copiedNum++;
                        }
                        else uncopiedNum++;
                    }
                    else{ // Overwrite same file
                        copyInto(item,destinationDir.resolvePath(destinationDir.nativePath + "\\" + item.name));
                        copiedNum++;
                    }

                }
                else{
                    skippedNum++;
                    }
            }
    }
如您所见,它执行递归目录\u listing()

在小文件和目录的情况下,它工作得很清楚

但是,例如,在以下情况下,它不起作用(似乎没有响应)

根目录:A

A包括500000多个子目录

每个子目录包括4或5个文件和一或两个子目录

子目录也包括4或5个文件

因此,我需要将“A”文件夹中的所有文件复制到特定文件夹(B!)

程序在循环之前先停止。i、 e.名为“A”的文件夹包含巨大的子文件夹,因此当程序运行以选择“A”文件夹时,它会在“A”文件夹列表中停止(在GetDirectoryListingAsync()处停止)。所以,实际上它不是递归的

这是我的全部源代码

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx"
                       width="800" height="600"
                       title="eveningCopier - Niao Jina"
                       creationComplete="initApp()">
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;

            public var sourceDir:File;
            public var destinationDir:File;

            public var totalDirNum:uint;
            public var totalFileNum:uint;
            public var copiedNum:uint;
            public var skippedNum:uint;
            public var uncopiedNum:uint;

            public var startTime:String;
            public var finishTime:String;

            /**
             * Boot Function 
             **/
            public function initApp():void{
                sourceBtn.addEventListener(MouseEvent.CLICK, click_sourceBtn);
                destinationBtn.addEventListener(MouseEvent.CLICK, click_destinationBtn);
                startBtn.addEventListener(MouseEvent.CLICK, click_startBtn);

                totalDirNum     = 0;
                totalFileNum    = 0;
                copiedNum       = 0;
                skippedNum      = 0;
                uncopiedNum     = 0;
            }

            /**
             * Event Listener when click "Source" button
             **/
            protected function click_sourceBtn(e:MouseEvent):void{
                sourceDir = new File();
                sourceDir.addEventListener(Event.SELECT, select_source);
                sourceDir.browseForDirectory("Please select a source directory...");
            }
            private function select_source(evt:Event):void {
                sourceTxt.text = sourceDir.nativePath;
            }

            /**
             * Event Listener when click "Destination" button
             **/
            protected function click_destinationBtn(e:MouseEvent):void{
                destinationDir = new File();
                destinationDir.addEventListener(Event.SELECT, destination_select);
                destinationDir.browseForDirectory("Please select a source directory...");
            }
            private function destination_select(evt:Event):void {
                destinationTxt.text = destinationDir.nativePath;
            }

            /**
             * Event Listener when click "Start" button
             **/
            protected function click_startBtn(e:MouseEvent):void{
                if(sourceTxt.text == "") Alert.show("Please select a source directory", "Warning");
                else if(destinationTxt.text == "") Alert.show("Please select a destination directory", "Warning");

                if(checkDir(sourceTxt.text) === false) Alert.show("A selected Source folder:\n" + sourceTxt.text + "\n is not exist. Please check!", "Warning");
                else if(checkDir(destinationTxt.text) === false) Alert.show("A selected Destination folder:\n" + destinationTxt.text + "\n is not exist. Please check!", "Warning");

                //Alert.show(checkFile("D:\\New Folder\\f.txt").toString());
                //Alert.show(checkDir("D:\\New Folder\\f.txt").toString());

                workedTextArea.text = "";
                currentLabel.text   = "";
                timeLabel.text  = "";
                totalDirLabel.text  = "";
                totalFileLabel.text = "";
                copiedLabel.text    = "";
                skippedLabel.text   = "";
                uncopiedLabel.text  = "";

                totalDirNum     = 0;
                totalFileNum    = 0;
                copiedNum       = 0;
                skippedNum      = 0;
                uncopiedNum     = 0;

                startTime = getNow() + "\n";

                getFileList(sourceTxt.text);
            }

            /**
             * Get a current date and time as format - YYYY-MM-DD HH:II:SS
             * 
             * @return String 
             **/
            public function getNow():String{
                var now:Date = new Date();
                return now.getFullYear() + "-" + now.getMonth() + "-" + now.getDate() + " " + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds();
            }

            /**
             * Check if the directory is exist.
             * @param dirName:String Path of the directory
             * @return Boolean true or false
             **/
            private function checkDir(dirName:String):Boolean{
                var dir:File = File.userDirectory.resolvePath(dirName);
                return dir.isDirectory;
            }

            /**
             * Check if the file is exist.
             * @param fileName:String Path of the file
             * @return Boolean true or false
             **/
            private function checkFile(fileName:String):Boolean{
                var file:File = File.userDirectory.resolvePath(fileName);
                return file.exists;
            }

            /**
             * Ananlyze a structure of files and directory
             * If is a folder, loop in its subfolder.
             * If is a file, copy to the destination folder
             *  
             * @param sourceDir:String
             **/
            private function getFileList(sourceDir:String):void{
                var file:File = File.userDirectory.resolvePath(sourceDir);
                file.addEventListener(FileListEvent.DIRECTORY_LISTING, directory_listing);
                file.getDirectoryListingAsync();
            }

            private function directory_listing(e:FileListEvent):void{
                var getfiles:Array = e.files;

                for each(var item:File in e.files){
                    trace(item.nativePath);
                    currentLabel.text = "Latest In : " + item.nativePath;

                    if(checkDir(item.nativePath)){
                        // It is a directory, more logic!
                        totalDirNum++;
                        item.addEventListener(FileListEvent.DIRECTORY_LISTING, directory_listing);
                        item.getDirectoryListingAsync();
                    }
                    else{
                        // It is a file, more logic!
                        totalFileNum++;
                        if(analyzeFile(item) === true){
                            if(overwriteChk.selected === false){ // Don't overwrite same file
                                if(checkFile(destinationDir.nativePath + "\\" + item.name) === false){
                                    copyInto(item, destinationDir.resolvePath(destinationDir.nativePath + "\\" + item.name));
                                    copiedNum++;
                                }
                                else uncopiedNum++;
                            }
                            else{ // Overwrite same file
                                copyInto(item, destinationDir.resolvePath(destinationDir.nativePath + "\\" + item.name));
                                copiedNum++;
                            }

                        }
                        else{
                            skippedNum++;
                        }
                    }
                }

                finishTime  = getNow();
                timeLabel.text = startTime + finishTime;

                totalDirLabel.text  = "Total Dir : " + totalDirNum;
                totalFileLabel.text = "Total Files : " + totalFileNum;
                copiedLabel.text    = "Copied Files : " + copiedNum;
                skippedLabel.text   = "Skipped Files : " + skippedNum;
                uncopiedLabel.text  = "Uncopied Files : " + uncopiedNum;
            }

            /**
             * Copy files
             * @param sourceFilePointer:File
             * @param destinationDirPointer:File
             * @return void
             **/
            private function copyInto(sourceFilePointer:File, destinationDirPointer:File):void{
                sourceFilePointer.copyTo(destinationDirPointer, true);

                if(logsChk.selected === true)
                    workedTextArea.text += sourceFilePointer.nativePath + "\n";
            }

            private function analyzeFile(filePointer:File):Boolean{
                //Alert.show(filePointer.extension + "\n" + filePointer.size + "\n" + filePointer.name.indexOf("@"));
                if((filePointer.extension) == null && (filePointer.size/1024 > 2) && (filePointer.name.indexOf("@") == -1))
                    return true;
                else
                    return false;
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <s:BorderContainer width="100%" height="100%">
        <s:VGroup width="90%" height="5%" left="0">
            <s:HGroup width="100%">
                <s:Button id="sourceBtn" label="Source"/>
                <s:TextInput id="sourceTxt" width="90%" fontSize="11"/>
            </s:HGroup>
            <s:HGroup width="100%">
                <s:Button id="destinationBtn" label="Destination"/>
                <s:TextInput id="destinationTxt" width="90%" fontSize="11"/>
            </s:HGroup>
        </s:VGroup>

        <s:Button id="startBtn" label="Start" height="48" top="0" right="0"/>

        <s:HGroup top="50" width="100%">            
            <s:Label id="currentLabel" width="90%" height="19" text="Latest In : "
                     textAlign="left" verticalAlign="middle"/>
            <s:CheckBox id="overwriteChk" label="Overwrite" selected="false"/>
            <s:CheckBox id="logsChk" label="Logs" selected="false"/>
        </s:HGroup>

        <s:TextArea id="workedTextArea" x="0" top="77" width="100%" height="90%" editable="false"/>

        <s:HGroup width="100%" height="5%" bottom="0">          
            <s:Label id="timeLabel" width="20%" height="100%" textAlign="center" verticalAlign="middle" fontSize="11"/>
            <s:Label id="totalDirLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
            <s:Label id="totalFileLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
            <s:Label id="copiedLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
            <s:Label id="skippedLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
            <s:Label id="uncopiedLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
        </s:HGroup>
    </s:BorderContainer>    

</s:WindowedApplication>


你的问题在执行时间内。如果你试图一次完成所有的事情,那么它将使用它能得到的所有CPU。如果一个线程被执行的时间超过X秒(通常为15秒),flash会中止它,说它花费的时间太多

在开始循环之前,使用getTimer()获取时间戳,并在循环中,在循环开始时检查startTimestamp-currentTimestamp是否小于5000(5秒)。如果是,请打断阵列并从您离开的位置重新开始(无论是否延迟,flash都会允许)

对于这种类型的操作,使用工人是有意义的,请检查

这里有一个抽象示例:

var counter:int = 0; // our progress
var startTime:int;

function increaseCounter():void
{
    startTime = getTimer();
    while(true) // infinite loop
    {
        if (getTimer() - startTime  > 5000)
        {
           increaseCounter();
           break;
        }

        counter++;

        if (counter >= int.MAX_VALUE) // our custom loop exit
        {
           trace(counter);
           break;
        }
    }
}

虽然这个线程看起来很旧,但我在这里发布了一个工作代码,我用给定的搜索字符串来搜索文件。它遍历所有子文件夹,与File.getDirectoryListing()相比响应速度非常快

这是我的密码

        protected function performSearch(event:MouseEvent):void
        {
            searchResults = new Array(); // instance variable
            foldersToBeSearched = new Array(); // instance variable

            // keep file search list empty at start
            fileSearchList.dataProvider = searchResults;

            // instance level variable to store search string
            searchString = searchText.text.toLowerCase();

            // add root folder to array
                    foldersToBeSearched.push(File.applicationStorageDirectory);
            findoutFolderNames(File.applicationStorageDirectory);

            // keep and eye on folder search counter
            setTimeout(checkAsyncFolderCounter, 500);

            // show controls if search is on
            showHideControlsAsPerSearchNeed();

        }

        // Because folder search is async hence use timeout to confirm if all folders are listed
        private function checkAsyncFolderCounter():void
        {
            if(foldersToBeSearched.length === counterCapturedLast)
            {
                // I am done searching all folders and subfolder
                // show this data now
                fileSearchList.dataProvider = searchResults;
                trace(searchResults.length);
            }
            else
            {
                // I am not yet done with folders...keep finding
                counterCapturedLast = foldersToBeSearched.length;
                setTimeout(checkAsyncFolderCounter, 500);
            }
        }

        // Find out all folders in this folder
        private function findoutFolderNames(folder:File):void
        {
            folder.addEventListener(FileListEvent.DIRECTORY_LISTING, directoryListingHandler);
            folder.getDirectoryListingAsync();
        }

        // CHECK ALL FILES AND FOLDER AND FIND FOR SEARCH STRING OTHERWISE ADD FOLDER TO SEARCH FOLDERS LIST
        private function directoryListingHandler(event:FileListEvent):void
        {
            event.target.removeEventListener(FileListEvent.DIRECTORY_LISTING, directoryListingHandler);
            var list:Array = event.files;

            for (var i:uint = 0; i < list.length; i++) 
            {
                var file:File = list[i];
                if(file.isDirectory)
                {
                    foldersToBeSearched.push(file);
                    findoutFolderNames(file);
                }
                else
                {
                    if(file.extension === "drl" && file.name.toLowerCase().indexOf(searchString) !== -1)
                    {
                        searchResults.push({label: file.name, creationDate: file.creationDate, nativePath: file.nativePath});
                    }
                }
            }

            trace("Folder Count " + foldersToBeSearched.length);
        }
受保护函数性能搜索(事件:MouseEvent):无效
{
searchResults=new Array();//实例变量
foldersToBeSearched=new Array();//实例变量
//开始时保持文件搜索列表为空
fileSearchList.dataProvider=搜索结果;
//用于存储搜索字符串的实例级变量
searchString=searchText.text.toLowerCase();
//将根文件夹添加到阵列
folderstobesearch.push(File.applicationStorageDirectory);
findoutFolderNames(File.applicationStorageDirectory);
//密切关注文件夹搜索计数器
setTimeout(checkAsyncFolderCounter,500);
//如果启用搜索,则显示控件
showHideControlsSperseArchNeed();
}
//因为文件夹搜索是异步的,所以使用超时来确认是否列出了所有文件夹
私有函数checkAsyncFolderCounter():void
{
if(folderstobesearch.length==counterpapturedlast)
{
//我已完成对所有文件夹和子文件夹的搜索
//现在显示此数据
fileSearchList.dataProvider=搜索结果;
跟踪(searchResults.length);
}
其他的
{
//我还没有完成文件夹…继续查找
counterCapturedLast=foldersToBeSearched.length;
setTimeout(checkAsyncFolderCounter,500);
}
}
//查找此文件夹中的所有文件夹
私有函数findoutFolderNames(文件夹:文件):void
{
folder.addEventListener(filelistent.DIRECTORY_LISTING,directoryListingHandler);
folder.getDirectoryListingAsync();
}
//检查所有文件和文件夹并查找搜索字符串,否则将文件夹添加到搜索文件夹列表
私有函数directoryListingHandler(事件:FileListEvent):void
{
event.target.removeEventListener(fileListent.DIRECTORY\u列表,directoryListingHandler);
变量列表:Array=event.files;
对于(变量i:uint=0;i
我为co例程编写了一个示例。什么是令人困惑的:共同例程还是工作者?我希望您在我的代码中提供一个示例。是的,这很清楚,但我不知道如何停止并记住该位置,然后从停止的位置重新启动。很抱歉,我不会为您编写代码,因为它没有那么小,我必须仔细阅读您的代码。据我所知,您正在使用一系列相互调用的方法。主程序应该执行时间检查,并且有一个方法,如果时间限制关闭,该方法将运行(或延迟)。记住位置可以通过计数器获得偏移量,因为您可以很容易地看到文件夹的长度(项目数)。因此,每次检查一个文件/文件夹时,都要使用一个计数器,并查看总长度中有多少个进程。你也可以做一个2d循环,没问题。但你不明白。程序在循环之前先停止。i、 名为“A”的文件夹包含巨大的子文件夹,所以当程序运行以选择“A”文件夹时,它会在“A”文件夹列表中停止。所以