Node.js-读取CSV文件时无法使用行号>500

Node.js - Reading CSV-file not working with line numbers > 500

本文关键字:gt 读取 js- CSV 文件 Node      更新时间:2023-09-26

我目前正在努力运行Node.js服务器。

我想做的事:

  • 将CSV文件从移动设备上载到我的本地服务器并保存在文件系统上
  • 读取.csv文件的每一行,并将每一行保存到我的MongoDB数据库中

上传和保存文件可以完美地工作。读取.csv文件并将每一行保存到数据库只适用于行号较小的文件。我不知道它停止工作时的确切行数。每次我读一个文件,它似乎都不一样。有时(如果行号大于1000(我使用的CSV阅读器甚至没有开始处理文件。其他时候,他只读100-200行,然后停下来。

以下是我上传文件的代码:

var fs = require('fs');
var sys = require("sys");
var url = require('url');
var http = require('http');
http.createServer(function(request, response) {
    sys.puts("Got new file to upload!");
    var urlString = url.parse(request.url).pathname;
    var pathParts = urlString.split("/");
    var deviceID = pathParts[1];
    var fileName = pathParts[2];
    sys.puts("DeviceID: " + deviceID);
    sys.puts("Filename: " + fileName);
    sys.puts("Start saving file");
    var tempFile = fs.createWriteStream(fileName);
    request.pipe(tempFile);
    sys.puts("File saved");
    // Starting a new child process which reads the file 
    // and inserts each row to the database
    var task = require('child_process').fork('databaseInsert.js');
    task.on('message', function(childResponse) {
        sys.puts('Finished child process!');
    });
    task.send({
        start : true,
        deviceID : deviceID,
        fileName : fileName
    });
    sys.puts("After task");
    response.writeHead(200, {
        "Content-Type" : "text/plain"
    });
    response.end('MESSAGE');
}).listen(8080);

这一切都很好。现在是子进程(databaseInsert.js(的代码:

var sys = require("sys");
var yaCSV = require('ya-csv');
var Db = require('mongodb').Db;
var dbServer = require('mongodb').Server;
process.on('message', function(info) {
    sys.puts("Doing work in child process");
    var fileName = info.fileName;
    var deviceID = info.deviceID;
    sys.puts("Starting db insert!");
    var dbClient = new Db('test', new dbServer("127.0.0.1", 27017, {}), {
        w : 1
    });
    dbClient.open(function(err, client) {
        if (err) {
            sys.puts(err);
        }
        dbClient.createCollection(deviceID, function(err, collection) {
            if (err) {
                sys.puts("Error creating collection: " + err);
            } else {
                sys.puts("Created collection: " + deviceID);
                var csvReader = yaCSV.createCsvFileReader(fileName, {
                    columnsFromHeader : true,
                    'separator' : ';'
                });
                csvReader.setColumnNames([ 'LineCounter', 'Time',  'Activity',
                        'Latitude', 'Longitude' ]);
                var lines = 0;
                csvReader.addListener('data', function(data) {
                    lines++;
                    sys.puts("Line: " + data.LineCounter);
                    var docRecord = {
                        fileName : fileName,
                        lineCounter : data.LineCounter,
                        time : data.Time,
                        activity : data.Activity,
                        latitude : data.Latitude,
                        longitude : data.Longitude
                    };
                    collection.insert(docRecord, {
                        safe : true
                    }, function(err, res) {
                        if (err) {
                            sys.puts(err);
                        }
                    });
                });
            }
        });
    });
    process.send('finished');
});

起初我没有使用儿童程序,但我的行为和现在一样。所以我测试了这个。

希望有一些Node.js经验的人能帮助我。

我认为您的问题是,您试图在tempFile仍在写入时读取它。现在,您正在将请求管道传输到文件流(并行和异步进行(并启动读取器进程。然后,读取器进程将开始与写入操作并行地读取文件。如果读卡器速度更快(通常会更快(,它会读取前几条记录,但随后会遇到文件结尾并停止读取。

为了解决此问题,您只能在写入完全完成后启动读取器进程,即将sys.puts("File.send");的部分放入tempFile.end(...)的回调中(请参阅http://nodejs.org/api/stream.html#stream_writable_end_chunk_encoding_callback)。

在文件仍在写入时读取该文件,类似于Unix中的tail命令,在我看来相当困难(在谷歌上搜索实现正确尾部的难度(。

您熟悉mongoimport/export吗?

我过去用这个从我的数据库导出到csv文件。。。因此,您可以在将其从移动客户端上传到服务器后执行相反的操作。

它来自shell,但您可以使用nodeJS_ChildSpawn 在代码中编写它