【发布时间】:2020-11-06 14:32:47
【问题描述】:
我想转换巨大的 CSV 文件并且转换只包括
- 删除特定列。
- 重命名特定列。
我已经在节点中实现了一个脚本,请在下面找到相同的内容。
for(const m of metadata) {
try {
tempm = m;
const pipelineAsync = promisify(pipeline);
if(m.path) {
let dir = `tmp/exports/${exportId}/processed/${m.type}`;
let fname = `${dir}/${m.sname}`;
fs.mkdirSync(dir,{recursive: true}, (err) => {
if(err) throw err;
});
await pipelineAsync(
fs.createReadStream(m.path),
csv.parse({delimiter: '\t', columns: true}),
csv.transform((input) => {
return Object.assign({}, input);
}),
csv.stringify({eol: true, record_delimiter: '\r\n', header: true, delimiter: '\t'}),
fs.createWriteStream(fname, {encoding: 'utf16le'})
)
}
} catch(e) {
tempm['transformed'] = false;
console.log(`error with ${m.path}`)
} finally {
tArr.push(tempm);
}
}
这在大多数情况下都有效,但对于巨大的 CSV 文件,并非所有数据都写入目标文件。如果源文件包含 1.2GB 的数据,那么我看到目标文件仅包含约 800 MB 的数据。因为,我在循环中处理文件,所以我还看到在同一执行流程中,另一个文件依次包含 80MB 数据,但目标文件仅包含 35MB 数据。
此外,问题是间歇性发生的。
既然我只想操作 csv 列,有没有更有效的方法来执行此操作而不是读取整个文件。
我还了解到 python/perl 能够处理/处理大型 csv 文件,也许我可以将处理部分作为单独的服务进行,然后从我的 node.js 应用程序中调用它。
另外,任何人都可以建议我如何解决并非所有数据都写入目标文件并且管道在两者之间完成的问题。
任何有关如何解决此问题的帮助都会非常有帮助。谢谢。
【问题讨论】:
-
一些可能对您有帮助的想法:unix.stackexchange.com/questions/317366/…
-
好吧,你确定要等到文件刷新到磁盘吗?
-
@Tarik 感谢您的回复,我该如何识别?我认为承诺管道将确保这一点。
标签: javascript python node.js csv perl