首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >迭代目录的最有效方法是什么?

迭代目录的最有效方法是什么?
EN

Stack Overflow用户
提问于 2017-06-19 04:52:01
回答 2查看 334关注 0票数 10

假设我有一个目录foo,其中有一些子目录。这些子目录中的每个子目录都有0到5个可变长度的文件,我希望处理这些文件。我的初始代码如下所示:

代码语言:javascript
复制
    pool.query(`
      SET SEARCH_PATH TO public,os_local;
    `).then(() => fs.readdirSync(srcpath)
        .filter(file => fs.lstatSync(path.join(srcpath, file)).isDirectory())
        .map(dir => {
          fs.access(`${srcpath + dir}/${dir}_Building.shp`, fs.constants.R_OK, (err) => {
            if (!err) {
              openShapeFile(`${srcpath + dir}/${dir}_Building.shp`).then((source) => source.read()
.then(function dbWrite (result) {
              if (result.done) {
                console.log(`done ${dir}`)
              } else {
    const query = `INSERT INTO os_local.buildings(geometry,
                  id,
                  featcode,
                  version)
                  VALUES(os_local.ST_GeomFromGeoJSON($1),
                  $2,
                  $3,
                  $4) ON CONFLICT (id) DO UPDATE SET
                    featcode=$3,
                    geometry=os_local.ST_GeomFromGeoJSON($1),
                    version=$4;`
                return pool.connect().then(client => {
                  client.query(query, [geoJson.split('"[[').join('[[').split(']]"').join(']]'),
                    result.value.properties.ID,
                    result.value.properties.FEATCODE,
                    version
                  ]).then((result) => {
                    return source.read().then(dbWrite)
                  }).catch((err) => {
                    console.log(err,
                      query,
                      geoJson.split('"[[').join('[[').split(']]"').join(']]'),
                      result.value.properties.ID,
                      result.value.properties.FEATCODE,
                      version
                    )
                    return source.read().then(dbWrite)
                  })
                  client.release()
                })
              }
            })).catch(err => console.log('No Buildings', err))
            }
          })

          fs.access(`${srcpath + dir}/${dir}__ImportantBuilding.shp`, fs.constants.R_OK, (err) => {
            //read file one line at a time
            //spin up connection in pg.pool, insert data
          })

          fs.access(`${srcpath + dir}/${dir}_Road.shp`, fs.constants.R_OK, (err) => {
            //read file one line at a time
            //spin up connection in pg.pool, insert data
          })

          fs.access(`${srcpath + dir}/${dir}_Glasshouse.shp`, fs.constants.R_OK, (err) => {
            //read file one line at a time
            //spin up connection in pg.pool, insert data
          })

          fs.access(`${srcpath + dir}/${dir}_RailwayStation.shp`, fs.constants.R_OK, (err) => {
            //read file one line at a time
            //spin up connection in pg.pool, insert data
          })
        })

这在很大程度上是可行的,但它最终不得不等待每个子目录中最长的文件被完全处理,导致在实践中总是只有一个数据库连接。

有没有一种方法可以重新设计,以便更好地利用我的计算资源,同时限制活动postgres连接的数量,并强制代码等待,直到连接可用?(我在node-postgres的pg poolConfig中将它们设置为20 )

EN

回答 2

Stack Overflow用户

发布于 2017-06-19 05:26:29

如果您需要在一定时间内轮流处理您的文件,那么您可以使用Streams、timers(用于调度)和process.nextTick()。nodejs中有用于理解流的great manual

票数 -1
EN

Stack Overflow用户

发布于 2017-06-27 02:12:06

下面是一个使用生成器获取目录内容的示例。您可以立即开始获取第一对文件,然后使用异步代码并行处理文件。

代码语言:javascript
复制
// Dependencies
const fs = require('fs');
const path = require('path');

// The generator function (note the asterisk)
function* getFilesInDirectory(fullPath, recursive = false) {
    // Convert file names to full paths
    let contents = fs.readdirSync(fullPath).map(file => {
        return path.join(fullPath, file);
    });

    for(let i = 0; i < contents.length; i++) {
        const childPath = contents[i];
        let stats = fs.statSync(childPath);
        if (stats.isFile()) {
            yield childPath;
        } else if (stats.isDirectory() && recursive) {
            yield* getFilesInDirectory(childPath, true);
        }
    }
}

用法:

代码语言:javascript
复制
function handleResults(results) {
    ... // Returns a promise
}

function processFile(file) {
    ... // Returns a promise
}

var files = getFilesInDirectory(__dirname, true);
var result = files.next();
var promises = [];
while(!result.done) {
    console.log(result.value);
    file = files.next();
    // Process files in parallel
    var promise = processFile(file).then(handleResults);
    promises.push(promise);
}

promise.all(promises).then() {
    console.log(done);
}
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44619434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档