【问题标题】:nodejs file line count returning undefinednodejs文件行数返回未定义
【发布时间】:2014-03-13 05:46:48
【问题描述】:

我是 node.js 的新手,所以请多多包涵。我需要一个函数来返回文件的行长。 我希望做类似的事情

file1 = line_length_func('file');
file2 = line_length_function('file');
if (file1 === file2) { console.log('same number of lines!');}

我一直在研究各种方法,使用 child.exec(cat file | wc -l) 但生成子实例有点复杂。我不确定如何将变量从我的孩子传递给父母,或者这样做是否是好的做法......

所以我尝试了这个 - 我看到 fs.open 中的 fd 返回了行数:

function get_lines(file) {
    var lines = fs.open(file, 'r', function(err, fd) {
        var lines = fd;
    });
}

a = get_lines('file.txt');
console.log(a);

但我总是不确定。

接下来我尝试的是:(感谢Andrey Sidorov's post

function get_line_count(file) {
    var count = 0;
    fs.createReadStream(file)
        .on('data', function(chunk) {
            for (var i = 0; i < chunk.length; i++)
                if (chunk[i] == 10) count++;
        })
        .on('end', function() {
            return count;
        });
}

var file1_lines = get_line_count('test.txt');
console.log(file1_lines);

但我得到了相同的结果。不明确的。

我还不习惯节点,所以任何帮助都会很棒!谢谢!

更新

行数现在似乎可以工作,但我仍然无法编写比较两者的函数。

function get_line_count(file, cb) {
    var count = 0;
    fs.createReadStream(file)
        .on('data', function(chunk) {
            for (var i = 0; i < chunk.length; i++)
                if (chunk[i] == 10) count++;
        })
        .on('end', function() {
            cb(null, count);
        })
        .once('error', cb);
}

var file1 = get_line_count('test.txt', function(err, lines) {
    if (err) return; // todo
    return lines;
});

var file2 = get_line_count('test2.txt', function(err, lines) {
    if (err) return; //todo
    return lines;
});

function same_line_length(len1, len2) {
    return len1===len2;
}

console.log(same_line_length(file1, file2));

这总是返回 true...

【问题讨论】:

  • 你应该阅读回调/异步执行:stackoverflow.com/a/4506306/3263412
  • 是的,我不习惯它的工作方式。感谢您的链接,我会在尝试解决这个问题时检查它。对我的功能有什么建议吗?我错过了什么?

标签: javascript node.js


【解决方案1】:

在函数get_line_count(file) 中,return count 用于匿名函数('end' 事件处理程序),而不用于get_line_count()。所以调用get_line_count() 将返回未定义。

假设你有一个函数需要知道行数:

function doSomething(count) {
  //your code
}

get_line_count的定义改为:

function get_line_count(file, cb) {
  var count = 0;
  fs.createReadStream(file)
    .on('data', function(chunk) {
        for (var i = 0; i < chunk.length; i++)
            if (chunk[i] == 10) count++;
    })
    .on('end', function() {
        // return count;
        cb(count);
    });
}

最后,像这样拨打get_line_count()

get_line_count(file, doSomething);

【讨论】:

  • 如何返回函数范围内的计数变量?
  • @Ptrkcon 唯一的方法是fs.readFileSync,但不推荐同步I/O,因为这会阻塞当前线程。
  • 见安德烈西多罗夫的回答。最好在回调函数中加入error参数。
【解决方案2】:

您的“get_line_count”在文件读取操作开始之前就完成了。它是异步 IO,如果这有助于考虑将您的函数命名为“start_file_linecount_sequence(name, oncomplete)” - 该函数将一些请求放入队列中并退出(几乎立即),并且您的处理程序会在稍后的某个时间点从事件循环中调用。

function get_line_count(file, cb) {
    var count = 0;
    fs.createReadStream(file)
        .on('data', function(chunk) {
            for (var i = 0; i < chunk.length; i++)
                if (chunk[i] == 10) count++;
        })
        .on('end', function() {
            cb(null, count)
        })
        .once('error', cb);
}

get_line_count('test.txt', console.log);

【讨论】:

  • 我之前没用过.once(event, listener)。它将 fs.readstream 中的任何错误传递给我的函数?
  • 只在调用参数(回调)一次 - 这样只报告第一个错误。 'error' 事件的通常约定是只有一个参数,通常是 js 错误对象
  • 'error' 是否总是只有一个参数?只是好奇以备将来参考。
  • 参见 docs.nodejitsu.com/articles/errors/… 关于 node.js @Ptrkcon 中的错误约定
  • 如果我尝试设置 get_line_count('test.txt', doSomething());到一个变量,我再次变得未定义......我正在尝试比较 2 个 get_line_counts。叹息。
【解决方案3】:

您尝试的两个函数都可以使用异步核心方法:fs.createReadStreamfs.open。要从这些函数中获取结果,您必须传入一个回调,如下所示:

function getLineCount(file, cb) {
    var count = 0;

    fs.createReadStream(file)
      .on('data', function(chunk) {
        for (var i = 0; i < chunk.length; i++)
        if (chunk[i] == 10) count++;
      })
      .once('error', cb)
      .on('end', function() {
        cb(null, count);
      });
}


getLineCount('example.txt', function(err, count) {
    if (err) return err; // do something about the error
    console.log(count);
});

更多关于闭包和回调的信息:What are Closures and Callbacks?

【讨论】:

  • fs.open 在回调中返回文件描述符,而不是文件内容。 cb也是第三个参数(第二个是'mode',例如'r')
  • 你是对的。在没有测试之前就跟随了操作。更新为使用fs.createReadStream,但我看到你先发布了这个@AndreySidorov。
猜你喜欢
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-01
  • 2016-04-24
  • 1970-01-01
  • 2020-11-28
相关资源
最近更新 更多