7.4 遍历目录

优质
小牛编辑
122浏览
2023-12-01

通过Entry的createReader方法可以创建DirectoryReader对象,而DirectoryReader对象的readEntries方法又可以读取出当前目录下的一级子目录和文件,依次类推就可以遍历整个目录。

下面我们来实践写一个遍历目录的函数。

首先通过chooseEntry方法获取Entry

chrome.fileSystem.chooseEntry({type: 'openDirectory'}, function(Entry) {
    //We'll do something with Entry later
});

接下来我们来获取Entry下的子目录和文件:

var dirReader = Entry.createReader();
dirReader.readEntries (function(Entries) {
    //We'll do something with Entries later
}, errorHandler);

获取到Entries之后要对其中的每个元素进行判断是目录还是文件,如果是文件直接输出文件名,如果还是目录,则继续遍历:

for(var i=0; i<Entries.length; i++){
    //We'll print name of this Entry
    if(Entries[i].isDirectory){
        //We'll get sub Entries for this Entry
    }
}

基本的过程已经搞清楚了,现在开始编写打印Entry名的函数。我们希望设计成以下输出格式:

The full path of the selected Entry
|-Entry1
| |-sub Entry1
| | |-File1 in sub Entry1
| |-File1 in Entry1
| |-File2 in Entry1
|-File1
|-File2

所以显示Entry需要指定当前的目录深度以输出相应的层次格式:

function echoEntry(depth, Entry){
    var tree = '|';
    for(var i=0; i<depth-1; i++){
        tree += ' |';
    }
    console.log(tree+'-'+Entry.name);
}

然后我们将获取子目录和文件的代码也封装成一个函数以便复用:

function getSubEntries(depth, Entry){
    var dirReader = Entry.createReader();
    dirReader.readEntries (function(Entries) {
        for(var i=0; i<Entries.length; i++){
            echoEntry(depth+1, Entries[i]);
            if(Entries[i].isDirectory){
                getSubEntries(depth+1, Entries[i]);
            }
        }
    }, errorHandler);
}

最后在chooseEntry获取到Entry之后调用getSubEntries函数:

chrome.fileSystem.chooseEntry({type: 'openDirectory'}, function(Entry) {
    console.log(Entry.fullPath);
    getSubEntries(0, Entry);
});

别忘了定义errorHandler函数用于抓取错误:

function errorHandler(e){
    console.log(e.message);
}

但是细心的读者会发现按照上面的写法会先显示一级目录,而后显示二级目录以此类推,并不是像我们所设计的那样展示实际的目录结构。这是因为getSubEntries函数得到的结果是以回调的形式传递的,也就是说getSubEntries函数未执行结束并不会阻塞循环体。这个问题只是在显示结果时会造成一点小麻烦,在实际遍历目录时我们并不在意哪些先得到哪些后得到。但为了使本小节的例子更加完善,现将代码修改如下:

var loopEntriesButton = document.getElementById('le');

loopEntriesButton.addEventListener('click', function(e) {
    chrome.fileSystem.chooseEntry({type: 'openDirectory'}, function(Entry) {
        document.getElementById('loopEntry').innerText = Entry.fullPath;
        getSubEntries(0, Entry, document.getElementById('loopEntry'));
    });
});

function getSubEntries(depth, Entry, parent){
    var dirReader = Entry.createReader();
    dirReader.readEntries(function(Entries) {
        for(var i=0; i<Entries.length; i++){
            var newParent = document.createElement('div');
            newParent.id = Date.now();
            newParent.innerText = echoEntry(depth+1, Entries[i]);
            parent.appendChild(newParent);
            if(Entries[i].isDirectory){
                getSubEntries(depth+1, Entries[i], newParent);
            }
        }
    }, errorHandler);
}

function echoEntry(depth, Entry){
    var tree = '|';
    for(var i=0; i<depth-1; i++){
        tree += ' |';
    }
    return (tree+'-'+Entry.name);
}

对应的HTML为:

<input type="button" id="le" value="Loop Entries" />
<div id="loopEntry"></div>

最终运行的结果如下图所示:

enter image description here
遍历目录所得到的结果