2

I try to calculate the size of all files in a given directory plus in all sub directories. This is what I have so far:

const fs = require('fs');

if (process.argv.length < 3) {
    console.log("no argument given");
    process.exit(-1);
}

const dir = process.argv[2];
let bytes = 0;

(getSize = async dir => {
    fs.readdir (dir, (err, list) => {
        list.forEach (file => {
            fs.stat (dir + file, (err, stat) => {
                if (stat.isDirectory()) {
                    getSize(dir + file + "/");
                } else {
                    console.log(file + " [" + stat.size + "]");
                    bytes += stat.size;
                }
            });
        });
    });
})(dir);

setTimeout(() => {
    console.log(bytes + " bytes");
    console.log(bytes / 1000 + " Kbytes");
}, 500);

Is there a way to avoid the timeout in the end to wait for the result? I heard it is possible with async/await but I don't know how. I also want to keep this general asynchron approach if possible.

1
  • 2
    fs.readdir is not based on promises, so even async dir makes no sense here.. You might want to look into using something to promisify the nodejs fs functions, You might find this useful -> github.com/normalize/mz Commented Jun 19, 2018 at 20:16

1 Answer 1

3

Promises are a bit easier to deal with. Thankfully, node has a promisify function to convert those callback-based functions into Promise-returning functions.

const { promisify } = require('util');
const fs = require('fs');
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);

async function getSize(dir) {
  const files = await readdir(dir);
  const sizes = await Promise.all(files.map(async file => {
    const stats = await stat(dir + file);
    return stats.isDirectory() ? getSize(dir + file + "/") : stats.size;
  }));
  return sizes.reduce((total, size) => total + size, 0);
}

const bytes = await getSize(process.argv[2]);
console.log(bytes + " bytes");
console.log(bytes / 1000 + " Kbytes");
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.