Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从具有多个级别的文件夹中获取子文件夹_Javascript_Directory_Subdirectory - Fatal编程技术网

Javascript 从具有多个级别的文件夹中获取子文件夹

Javascript 从具有多个级别的文件夹中获取子文件夹,javascript,directory,subdirectory,Javascript,Directory,Subdirectory,我有一个代码,可以检查子文件夹中的所有文件是否有一个文件夹。但是,如何才能将其更改为不仅检查子文件夹级别,而且检查子文件夹的子文件夹等等 这是我为文件夹及其子文件夹提供的代码: var fso = new ActiveXObject("Scripting.FileSystemObject"); fso = fso.getFolder(path); var subfolders = new Object();

我有一个代码,可以检查子文件夹中的所有文件是否有一个文件夹。但是,如何才能将其更改为不仅检查子文件夹级别,而且检查子文件夹的子文件夹等等

这是我为文件夹及其子文件夹提供的代码:

            var fso = new ActiveXObject("Scripting.FileSystemObject");
            fso = fso.getFolder(path);
            var subfolders = new Object();
            subfolders = fso.SubFolders;
            var oEnumerator = new Enumerator(subfolders);
            for (;!oEnumerator.atEnd(); oEnumerator.moveNext())
            {
                var itemsFolder = oEnumerator.item().Files;
                var oEnumerator2 = new Enumerator(itemsFolder);
                var clientFileName = null;

                for(;!oEnumerator2.atEnd(); oEnumerator2.moveNext())
                {
                    var item = oEnumerator2.item();
                    var itemName = item.Name;
                    var checkFile = itemName.substring(itemName.length - 3);
                    if(checkFile == ".ac")
                    {
                        var clientFileName = itemName;
                        break;
                    }
                }
            }

在每个级别的子文件夹上,如果可以找到.ac文件,我需要检查所有的文件。

我在评论中提到的解决方案是这样的(我对ActiveX不太了解,所以有很多评论,希望您可以轻松更正错误):


同样,要注意上面的代码:我没有对它进行测试,也不太了解ActiveX,我只是把你的代码修改了一下,让它可以在所有的子文件夹中查看。

我在评论中提到的解决方案看起来像这样(我对ActiveX了解不多,因此有很多评论,希望您可以轻松更正任何错误):


同样,请注意上面的代码:我没有测试它,也不太了解ActiveX,我只是将您的代码更改为可以在所有子文件夹中查看。

您需要的是一个递归函数。下面是一个简单的递归函数,它迭代所提供路径中的每个文件,然后进行递归调用来迭代每个子文件夹文件。对于遇到的每个文件,此函数调用提供的回调(在这里执行任何处理逻辑)

功能:

function iterateFiles(path, recursive, actionPerFileCallback){ 
    var fso = new ActiveXObject("Scripting.FileSystemObject"); 
    //Get current folder
    folderObj = fso.GetFolder(path);

    //Iterate thru files in thisFolder
    for(var fileEnum = new Enumerator(folderObj.Files); !fileEnum.atEnd(); fileEnum.moveNext()){
      //Get current file
      var fileObj = fso.GetFile(fileEnum.item());

      //Invoke provided perFile callback and pass the current file object
      actionPerFileCallback(fileObj);
    }

    //Recurse thru subfolders
    if(recursive){
      //Step into each sub folder
      for(var subFolderEnum = new Enumerator(folderObj.SubFolders); !subFolderEnum.atEnd(); subFolderEnum.moveNext()){
          var subFolderObj = fso.GetFolder(subFolderEnum.item());

          //Make recursive call
          iterateFiles(subFolderObj.Path, true, actionPerFileCallback);
        }   
    }
};
function iterateFiles(path, recursive, actionPerFileCallback, actionPerFolderCallback, useFnReturnValue, callingContext, updateContextFn){ 
    var fso = new ActiveXObject("Scripting.FileSystemObject"); 
    //If 'useFnReturnValue' is true, then iterateFiles() should return false IFF a callback fails. 
    //This function simply tests that case.
    var failOnCallbackResult = function(cbResult){
        return !cbResult && useFnReturnValue;
    }

    //Context that is passed to each callback
    var context = {};

    //Handle inputs
    if(callingContext != null){
        context.callingContext = callingContext;
    }

    //Get current folder
    context.folderObj = fso.GetFolder(path);

    //Do actionPerFolder callback if provided
    if(actionPerFolderCallback != null){
        var cbResult = Boolean(actionPerFolderCallback(context));
        if (failOnCallbackResult(cbResult)){
            return false;
        }
    }

    //Iterate thru files in thisFolder
    for(var fileEnum = new Enumerator(context.folderObj.Files); !fileEnum.atEnd(); fileEnum.moveNext()){
        //Get current file
        context.fileObj = fso.GetFile(fileEnum.item());

        //Invoke provided perFile callback function with current context
        var cbResult = Boolean(actionPerFileCallback(context));
        if (failOnCallbackResult(cbResult)){
            return false;
        }
     }

     //Recurse thru subfolders
     if(recursive){
         //Step into sub folder
         for(var subFolderEnum = new Enumerator(context.folderObj.SubFolders); !subFolderEnum.atEnd(); subFolderEnum.moveNext()){
             var subFolderObj = fso.GetFolder(subFolderEnum.item());

             //New calling context that will be passed into recursive call
             var newCallingContext;

             //Provide caller a chance to update the calling context with the new subfolder before making the recursive call
             if(updateContextFn != null){
                 newCallingContext = updateContextFn(subFolderObj, callingContext); 
             }

             //Make recursive call
             var cbResult = iterateFiles(subFolderObj.Path, true, actionPerFileCallback, actionPerFolderCallback, useFnReturnValue, newCallingContext, updateContextFn);
             if (failOnCallbackResult(cbResult)){
                 return false;
             }
         }
     }
     return true; //if we made it here, then all callbacks were successful 
 };
用法(这里我传入一个匿名函数,为每个文件调用get):

现在..这是一个非常基本的例子。下面是一个类似函数的更复杂的实现。在这个函数中,我们可以像以前一样递归地迭代每个文件。但是,现在调用方可以为函数提供一个“调用上下文”,然后将其传递回回调。这可能非常强大,因为现在调用方可以使用它自己的闭包中以前的信息。此外,我为调用方提供了在每个递归级别更新调用上下文的机会。在设计此函数时,出于我的特定需要,有必要提供检查每个回调函数是否成功的选项。因此,您将在是函数。我还包括对遇到的每个文件夹执行回调的选项

更复杂的功能:

function iterateFiles(path, recursive, actionPerFileCallback, actionPerFolderCallback, useFnReturnValue, callingContext, updateContextFn){ 
    var fso = new ActiveXObject("Scripting.FileSystemObject"); 
    //If 'useFnReturnValue' is true, then iterateFiles() should return false IFF a callback fails. 
    //This function simply tests that case.
    var failOnCallbackResult = function(cbResult){
        return !cbResult && useFnReturnValue;
    }

    //Context that is passed to each callback
    var context = {};

    //Handle inputs
    if(callingContext != null){
        context.callingContext = callingContext;
    }

    //Get current folder
    context.folderObj = fso.GetFolder(path);

    //Do actionPerFolder callback if provided
    if(actionPerFolderCallback != null){
        var cbResult = Boolean(actionPerFolderCallback(context));
        if (failOnCallbackResult(cbResult)){
            return false;
        }
    }

    //Iterate thru files in thisFolder
    for(var fileEnum = new Enumerator(context.folderObj.Files); !fileEnum.atEnd(); fileEnum.moveNext()){
        //Get current file
        context.fileObj = fso.GetFile(fileEnum.item());

        //Invoke provided perFile callback function with current context
        var cbResult = Boolean(actionPerFileCallback(context));
        if (failOnCallbackResult(cbResult)){
            return false;
        }
     }

     //Recurse thru subfolders
     if(recursive){
         //Step into sub folder
         for(var subFolderEnum = new Enumerator(context.folderObj.SubFolders); !subFolderEnum.atEnd(); subFolderEnum.moveNext()){
             var subFolderObj = fso.GetFolder(subFolderEnum.item());

             //New calling context that will be passed into recursive call
             var newCallingContext;

             //Provide caller a chance to update the calling context with the new subfolder before making the recursive call
             if(updateContextFn != null){
                 newCallingContext = updateContextFn(subFolderObj, callingContext); 
             }

             //Make recursive call
             var cbResult = iterateFiles(subFolderObj.Path, true, actionPerFileCallback, actionPerFolderCallback, useFnReturnValue, newCallingContext, updateContextFn);
             if (failOnCallbackResult(cbResult)){
                 return false;
             }
         }
     }
     return true; //if we made it here, then all callbacks were successful 
 };
用法:

//Note: The 'lib' object used below is just a utility library I'm using.
function copyFolder(fromPath, toPath, overwrite, recursive){

    var actionPerFileCallback = function(context){
        var destinationFolder = context.callingContext.toPath;
        var destinationPath = lib.buildPath([context.callingContext.toPath, context.fileObj.Name]);
        lib.createFolderIfDoesNotExist(destinationFolder);
        return copyFile(context.fileObj.Path, destinationPath, context.callingContext.overwrite);
    };

    var actionPerFolderCallback = function(context){
        var destinationFolder = context.callingContext.toPath;
        return lib.createFolderIfDoesNotExist(destinationFolder);
    };

    var callingContext = {
        fromPath : fromPath,
        toPath : lib.buildPath([toPath, fso.GetFolder(fromPath).Name]), //include folder in copy
        overwrite : overwrite,
        recursive : recursive
    };

    var updateContextFn = function(currentFolderObj, previousCallingContext){
        return {
            fromPath : currentFolderObj.Path,
            toPath : lib.buildPath([previousCallingContext.toPath, currentFolderObj.Name]), 
            overwrite : previousCallingContext.overwrite,
            recursive : previousCallingContext.recursive
        }
    }
    return iterateFiles(fromPath, recursive, actionPerFileCallback, null, true, callingContext, updateContextFn);
};

我知道这个问题很老,但我无意中发现了它,希望我的答案能帮助别人!

您需要的是一个递归函数。下面是一个简单的递归函数,它迭代提供的路径中的每个文件,然后递归调用迭代每个子文件夹文件。对于遇到的每个文件,此函数在发出一个提供的回调(在这里您可以执行任何处理逻辑)

功能:

function iterateFiles(path, recursive, actionPerFileCallback){ 
    var fso = new ActiveXObject("Scripting.FileSystemObject"); 
    //Get current folder
    folderObj = fso.GetFolder(path);

    //Iterate thru files in thisFolder
    for(var fileEnum = new Enumerator(folderObj.Files); !fileEnum.atEnd(); fileEnum.moveNext()){
      //Get current file
      var fileObj = fso.GetFile(fileEnum.item());

      //Invoke provided perFile callback and pass the current file object
      actionPerFileCallback(fileObj);
    }

    //Recurse thru subfolders
    if(recursive){
      //Step into each sub folder
      for(var subFolderEnum = new Enumerator(folderObj.SubFolders); !subFolderEnum.atEnd(); subFolderEnum.moveNext()){
          var subFolderObj = fso.GetFolder(subFolderEnum.item());

          //Make recursive call
          iterateFiles(subFolderObj.Path, true, actionPerFileCallback);
        }   
    }
};
function iterateFiles(path, recursive, actionPerFileCallback, actionPerFolderCallback, useFnReturnValue, callingContext, updateContextFn){ 
    var fso = new ActiveXObject("Scripting.FileSystemObject"); 
    //If 'useFnReturnValue' is true, then iterateFiles() should return false IFF a callback fails. 
    //This function simply tests that case.
    var failOnCallbackResult = function(cbResult){
        return !cbResult && useFnReturnValue;
    }

    //Context that is passed to each callback
    var context = {};

    //Handle inputs
    if(callingContext != null){
        context.callingContext = callingContext;
    }

    //Get current folder
    context.folderObj = fso.GetFolder(path);

    //Do actionPerFolder callback if provided
    if(actionPerFolderCallback != null){
        var cbResult = Boolean(actionPerFolderCallback(context));
        if (failOnCallbackResult(cbResult)){
            return false;
        }
    }

    //Iterate thru files in thisFolder
    for(var fileEnum = new Enumerator(context.folderObj.Files); !fileEnum.atEnd(); fileEnum.moveNext()){
        //Get current file
        context.fileObj = fso.GetFile(fileEnum.item());

        //Invoke provided perFile callback function with current context
        var cbResult = Boolean(actionPerFileCallback(context));
        if (failOnCallbackResult(cbResult)){
            return false;
        }
     }

     //Recurse thru subfolders
     if(recursive){
         //Step into sub folder
         for(var subFolderEnum = new Enumerator(context.folderObj.SubFolders); !subFolderEnum.atEnd(); subFolderEnum.moveNext()){
             var subFolderObj = fso.GetFolder(subFolderEnum.item());

             //New calling context that will be passed into recursive call
             var newCallingContext;

             //Provide caller a chance to update the calling context with the new subfolder before making the recursive call
             if(updateContextFn != null){
                 newCallingContext = updateContextFn(subFolderObj, callingContext); 
             }

             //Make recursive call
             var cbResult = iterateFiles(subFolderObj.Path, true, actionPerFileCallback, actionPerFolderCallback, useFnReturnValue, newCallingContext, updateContextFn);
             if (failOnCallbackResult(cbResult)){
                 return false;
             }
         }
     }
     return true; //if we made it here, then all callbacks were successful 
 };
用法(这里我传入一个匿名函数,为每个文件调用get):

现在..这是一个非常基本的例子。下面是一个类似函数的更复杂的实现。在这个函数中,我们可以像以前一样递归地迭代每个文件。但是,现在调用方可以为函数提供一个“调用上下文”,然后将其传递回回调。这可能非常强大,因为现在调用方可以使用它自己的闭包中以前的信息。此外,我为调用方提供了在每个递归级别更新调用上下文的机会。在设计此函数时,出于我的特定需要,有必要提供检查每个回调函数是否成功的选项。因此,您将在是函数。我还包括对遇到的每个文件夹执行回调的选项

更复杂的功能:

function iterateFiles(path, recursive, actionPerFileCallback, actionPerFolderCallback, useFnReturnValue, callingContext, updateContextFn){ 
    var fso = new ActiveXObject("Scripting.FileSystemObject"); 
    //If 'useFnReturnValue' is true, then iterateFiles() should return false IFF a callback fails. 
    //This function simply tests that case.
    var failOnCallbackResult = function(cbResult){
        return !cbResult && useFnReturnValue;
    }

    //Context that is passed to each callback
    var context = {};

    //Handle inputs
    if(callingContext != null){
        context.callingContext = callingContext;
    }

    //Get current folder
    context.folderObj = fso.GetFolder(path);

    //Do actionPerFolder callback if provided
    if(actionPerFolderCallback != null){
        var cbResult = Boolean(actionPerFolderCallback(context));
        if (failOnCallbackResult(cbResult)){
            return false;
        }
    }

    //Iterate thru files in thisFolder
    for(var fileEnum = new Enumerator(context.folderObj.Files); !fileEnum.atEnd(); fileEnum.moveNext()){
        //Get current file
        context.fileObj = fso.GetFile(fileEnum.item());

        //Invoke provided perFile callback function with current context
        var cbResult = Boolean(actionPerFileCallback(context));
        if (failOnCallbackResult(cbResult)){
            return false;
        }
     }

     //Recurse thru subfolders
     if(recursive){
         //Step into sub folder
         for(var subFolderEnum = new Enumerator(context.folderObj.SubFolders); !subFolderEnum.atEnd(); subFolderEnum.moveNext()){
             var subFolderObj = fso.GetFolder(subFolderEnum.item());

             //New calling context that will be passed into recursive call
             var newCallingContext;

             //Provide caller a chance to update the calling context with the new subfolder before making the recursive call
             if(updateContextFn != null){
                 newCallingContext = updateContextFn(subFolderObj, callingContext); 
             }

             //Make recursive call
             var cbResult = iterateFiles(subFolderObj.Path, true, actionPerFileCallback, actionPerFolderCallback, useFnReturnValue, newCallingContext, updateContextFn);
             if (failOnCallbackResult(cbResult)){
                 return false;
             }
         }
     }
     return true; //if we made it here, then all callbacks were successful 
 };
用法:

//Note: The 'lib' object used below is just a utility library I'm using.
function copyFolder(fromPath, toPath, overwrite, recursive){

    var actionPerFileCallback = function(context){
        var destinationFolder = context.callingContext.toPath;
        var destinationPath = lib.buildPath([context.callingContext.toPath, context.fileObj.Name]);
        lib.createFolderIfDoesNotExist(destinationFolder);
        return copyFile(context.fileObj.Path, destinationPath, context.callingContext.overwrite);
    };

    var actionPerFolderCallback = function(context){
        var destinationFolder = context.callingContext.toPath;
        return lib.createFolderIfDoesNotExist(destinationFolder);
    };

    var callingContext = {
        fromPath : fromPath,
        toPath : lib.buildPath([toPath, fso.GetFolder(fromPath).Name]), //include folder in copy
        overwrite : overwrite,
        recursive : recursive
    };

    var updateContextFn = function(currentFolderObj, previousCallingContext){
        return {
            fromPath : currentFolderObj.Path,
            toPath : lib.buildPath([previousCallingContext.toPath, currentFolderObj.Name]), 
            overwrite : previousCallingContext.overwrite,
            recursive : previousCallingContext.recursive
        }
    }
    return iterateFiles(fromPath, recursive, actionPerFileCallback, null, true, callingContext, updateContextFn);
};

我知道这个问题很老,但我偶然发现了它,希望我的答案能帮助别人!

创建一个递归函数,检查文件,然后调用所有子文件夹。(顺便说一下:
itemName.substring(itemName.length-3)
可能会对名称少于3个字符的文件产生错误)你能再详细一点吗?创建一个递归函数,检查文件,然后为所有子文件夹调用它自己。(顺便问一下:
itemName.substring(itemName.length-3)
可能会对名称小于3个字符的文件产生错误)你能再详细一点吗?