如何使用 javascript 循环访问文件系统目录和文件
How to iterate through file system directories and files using javascript?
我正在使用Javascript编写一个应用程序,该应用程序将与Phonegap一起使用以制作Android应用程序。我正在使用Phonegap文件API来读取目录和文件。相关代码如下所示:
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
//
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail);
}
function onFileSystemSuccess(fileSystem) {
fileSystem.root.getDirectory("/sdcard", {create: false, exclusive: false}, getDirSuccess, fail);
}
function getDirSuccess(dirEntry) {
// Get a directory reader
var directoryReader = dirEntry.createReader();
// Get a list of all the entries in the directory
directoryReader.readEntries(readerSuccess,fail);
}
var numDirs = 0;
var numFiles = 0;
function readerSuccess(entries) {
var i;
for (i=0; i<entries.length; i++)
{
if(entries[i].isFile === true)
{
numFiles++;
entries[i].file(fileSuccess,fail);
}
else if (entries[i].isDirectory === true)
{
numDirs++;
getDirSuccess(entries[i]);
}
}
}
因此,截至目前,该程序运行良好。读卡器将读取/sdcard 目录的内容。如果遇到文件,它将调用 fileSuccess(为了简洁起见,我在代码中排除了它),如果遇到另一个目录,它将再次调用 getDirSuccess。我的问题是:我怎么知道何时读取整个/sdcard 目录?我想不出在不多次遍历/sdcard 目录的情况下完成此操作的好方法。任何想法都值得赞赏,提前感谢您!
+1 在一个好问题上,因为我无论如何都必须自己这样做。我会使用旧的设置超时技巧。一旦取消不再发生,您就知道您已完成并且可以触发您的事件,但只需确保它只触发一次。
这就是我的意思,我命名变量很长只是为了更具可读性(不是我的风格)......
// create timeout var outside your "readerSuccess" function scope
var readerTimeout = null, millisecondsBetweenReadSuccess = 100;
function readerSuccess(entries) {
var i = 0, len = entries.length;
for (; i < len; i++) {
if (entries[i].isFile) {
numFiles++;
entries[i].file(fileSuccess,fail);
} else if (entries[i].isDirectory) {
numDirs++;
getDirSuccess(entries[i]);
}
if (readerTimeout) {
window.clearTimeout(readerTimeout);
}
}
if (readerTimeout) {
window.clearTimeout(readerTimeout);
}
readerTimeout = window.setTimeout(weAreDone, millisecondsBetweenReadSuccess);
}
// additional event to call when totally done
function weAreDone() {
// do something
}
所以这里的逻辑是,当你阅读东西时,你不断取消调用"weAreDone"函数。不确定这是最好的方法还是更有效,但在给定适当的"毫秒之间读取成功"的情况下,它不会导致多个循环。
您可以使用计数器来查看仍需要调用多少回调,而不是使用 setTimeout(如果您的设备速度非常慢,这可能会失败)。如果计数器达到零,则全部完成:)
这是递归代码:
var fileSync = new function(){
this.filesystem = null;
this.getFileSystem = function(callback){
var rfs = window.requestFileSystem || window.webkitRequestFileSystem;
rfs(
1// '1' means PERSISTENT
, 0// '0' is about max. storage size: 0==we don't know yet
, function(filesystem){
fileSync.filesystem = filesystem;
callback(filesystem);
}
, function(e){
alert('An error occured while requesting the fileSystem:'n'n'+ e.message);
}
);
}
this.readFilesFromReader = function(reader, callback, recurse, recurseFinishedCallback, recurseCounter)
{
if (recurse && !recurseCounter)
recurseCounter = [1];
reader.readEntries(function(res){
callback(res);
if (recurse)
{
for (var i=0; i<res.length; i++) {
/* only handle directories */
if (res[i].isDirectory == true)
{
recurseCounter[0]++;
fileSync.readFilesFromReader(res[i].createReader(), callback, recurse, recurseFinishedCallback, recurseCounter);
}
}
}
/* W3C specs say: Continue calling readEntries() until an empty array is returned.
* You have to do this because the API might not return all entries in a single call.
* But... Phonegap doesn't seem to accommodate this, and instead always returns the same dir-entries... OMG, an infinite loop is created :-/
*/
//if (res.length)
// fileSync.readFilesFromReader(reader, callback, recurse, recurseFinishedCallback, recurseCounter);
//else
if (recurse && --recurseCounter[0] == 0)
{
recurseFinishedCallback();
}
}
, function(e){
fileSync.onError(e);
if (recurse && --recurseCounter[0] == 0)
recurseFinishedCallback();
});
};
this.onError = function(e){
utils.log('onError in fileSync: ' + JSON.stringify(e));
if (utils.isDebugEnvironment())
alert('onError in fileSync: '+JSON.stringify(e));
}
}
var utils = new function(){
this.log = function(){
for (var i=0;i<arguments.length;i++)
console.log(arguments[i]);
}
this.isDebugEnvironment = function(){ return true }// simplified
}
测试此内容的示例代码:
var myFiles = [];
var directoryCount = 0;
window.onerror = function(){ alert('window.onerror='n'n' + arguments.join(''n')) }
var gotFilesCallback = function(entries)
{
for (var i=0;i<entries.length;i++)
{
if (entries[i].isFile == true)
myFiles.push(entries[i].fullPath)
else
++directoryCount;
}
}
var allDoneCallback = function(){
alert('All files and directories were read.'nWe found '+myFiles.length+' files and '+directoryCount+' directories, shown on-screen now...');
var div = document.createElement('div');
div.innerHTML = '<div style="border: 1px solid red; position: absolute;top:10px;left:10%;width:80%; background: #eee;">'
+ '<b>Filesystem root:</b><i>' + fileSync.filesystem.root.fullPath + '</i><br><br>'
+ myFiles.join('<br>').split(fileSync.filesystem.root.fullPath).join('')
+ '</div>';
document.body.appendChild(div);
}
/* on-device-ready / on-load, get the filesystem, and start reading files */
var docReadyEvent = window.cordova ? 'deviceready':'load';
document.addEventListener(docReadyEvent, function()
{
fileSync.getFileSystem(function(filesystem){
var rootDirReader = filesystem.root.createReader();
fileSync.readFilesFromReader(rootDirReader, gotFilesCallback, true, allDoneCallback);
})
}, false);
相关文章:
- 节点Js:How to catch a“;没有这样的文件或目录“;读取线模块出错
- qoxdoo中的离线存储是否与所有浏览器和本地文件系统兼容
- 内容安全策略指令:;脚本src'self'blob:文件系统:chrome扩展资源:“;获取是否时
- 是否有WebKit的实现可以方便地访问本地文件系统
- 使用 Javascript 在文件系统中打开 PDF
- Chrome/Tampermonkey 用户脚本存储在文件系统上的什么位置
- 在 Lua/Luci 服务器上使用 HTML/JavaScript 下载服务器根文件系统中的现有文件
- Html 5文件系统API,我得到一个DOMError“;NotSupporteError”;
- windows文件系统中的nodejs路径错误4058 ENOENT
- 在WinJS中将文件下载到文件系统
- NodeJ将文件从请求流式传输到文件系统,而不是内存
- 从firefox插件访问文件系统/目录路径
- 如何使用 javascript 循环访问文件系统目录和文件
- 使用 Node.js 将文件系统中的目录结构转换为 JSON
- 文件系统API-递归列出从目录拖放文件
- 如何验证本地文件系统目录路径
- 在目录更新后读取HTML5文件系统
- 使用文件系统api检索所有目录
- 可视化文件系统目录树字符串
- 节点文件系统 在发布路由上创建目录和文件