Actionscript 3 列出大量的文件和目录,包括AdobeAIR中的子目录
我正在尝试列出文件和目录,并将所有现有文件复制到任何其他文件夹中 顺便说一下,有许多文件和目录超过10万个以上 下面是代码的一部分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
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”文件夹列表中停止。所以