Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/437.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js中的大型CSV到JSON/对象_Javascript_Json_Node.js_Csv - Fatal编程技术网

Javascript Node.js中的大型CSV到JSON/对象

Javascript Node.js中的大型CSV到JSON/对象,javascript,json,node.js,csv,Javascript,Json,Node.js,Csv,我正在尝试做一些事情,似乎它不仅应该是相当简单的完成,但一个足够普遍的任务,将有直接的包可以做它。我希望获取一个大型CSV文件(从关系数据库表导出)并将其转换为JavaScript对象数组。此外,我想将其导出到.json文件fixture 示例CSV: a,b,c,d 1,2,3,4 5,6,7,8 ... 所需的JSON: [ {"a": 1,"b": 2,"c": 3,"d": 4}, {"a": 5,"b": 6,"c": 7,"d": 8}, ... ] 我尝试了几个节点CSV解析器

我正在尝试做一些事情,似乎它不仅应该是相当简单的完成,但一个足够普遍的任务,将有直接的包可以做它。我希望获取一个大型CSV文件(从关系数据库表导出)并将其转换为JavaScript对象数组。此外,我想将其导出到
.json
文件fixture

示例CSV:

a,b,c,d
1,2,3,4
5,6,7,8
...
所需的JSON:

[
{"a": 1,"b": 2,"c": 3,"d": 4},
{"a": 5,"b": 6,"c": 7,"d": 8},
...
]
我尝试了几个节点CSV解析器、拖缆、自称的CSV到JSON库,但我似乎无法得到我想要的结果,或者如果我可以,它只能在文件更小的情况下工作。我的文件大小接近1GB,有大约40m行(这将创建40m个对象)。我希望它需要流式处理输入和/或输出,以避免内存问题

以下是我尝试过的软件包:

  • (这是可行的,但事实并非如此 由于我经常修改数据集,所以速度非常慢,甚至毫无用处。解析一个60 MB的csv文件花了将近3个小时)
  • (似乎不是 用于将csv转换为其他格式)

我正在使用Node 0.10.6,希望得到一个关于如何轻松实现这一点的建议。滚动我自己的可能是最好的,但我不确定从何处开始使用Node的所有流媒体功能,特别是因为它们在0.10.x中更改了API。

虽然这远不是一个完整的答案,但您可能能够将您的解决方案基于此。改编自自述文件的示例:

    var es = require('event-stream')
    es.pipeline(                         //connect streams together with `pipe`
      process.openStdin(),              //open stdin
      es.split(),                       //split stream to break on newlines
      es.map(function (data, callback) { //turn this async function into a stream
        callback(null
          , JSON.stringify(parseCSVLine(data)))  // deal with one line of CSV data
      }), 
      process.stdout
      )
之后,我希望每行都有一堆字符串化的JSON对象。 然后需要将其转换为一个数组,您可以使用该数组将
追加到每一行的末尾,在最后一行将其删除,然后将
[
]
添加到文件的开头和结尾

parseCSVLine
函数必须配置为将CSV值分配给正确的对象属性。在传递文件的第一行之后,这可以相当容易地完成


我注意到库没有在0.10上测试(至少Travis没有测试),所以要小心。可以自己在源代码上运行
npm测试。

检查node.js csvtojson模块,该模块可用作库、命令行工具或web服务器插件。 源代码可在以下位置找到:

或从NPM repo安装:

npm install -g csvtojson
它支持任意大小的csv数据/字段类型/嵌套json等一系列功能

范例

var Converter=require("csvtojson").core.Converter;

var csvConverter=new Converter({constructResult:false, toArrayString:true}); // The constructResult parameter=false will turn off final result construction in memory for stream feature. toArrayString will stream out a normal JSON array object.

var readStream=require("fs").createReadStream("inputData.csv"); 

var writeStream=require("fs").createWriteStream("outpuData.json");

readStream.pipe(csvConverter).pipe(writeStream);
您还可以将其用作cli工具:

csvtojson myCSVFile.csv

我发现使用csvtojson读取csv数据更简单

代码如下:

var Converter=require(“csvtojson”).Converter;
var转换器=新转换器({});
converter.fromFile(“sample.csv”),函数(err,result){
var csvData=JSON.stringify
([
{resultdata:result[0]},
{resultdata:result[1]},
{resultdata:result[2]},
{resultdata:result[3]},
{resultdata:result[4]}
]);
csvData=JSON.parse(csvData);
console.log(csvData);

});我建议自己实现逻辑。Node.js实际上非常擅长这类任务

下面的解决方案是使用流,因为它们不会占用您的内存

再进行 代码
从“through2”导入through2
从“split2”导入split2
fs.createReadStream(“”)
//逐行阅读
.管道(拆分2())
//解析CSV行
.pipe(parseCSV())
//处理你的记录
.pipe(processRecord())
const parseCSV=()=>{
让templateKeys=[]
让parseHeadline=true
通过2.obj返回((数据、enc、cb)=>{
如果(标题){
templateKeys=数据
.toString()
.split(“;”)
parseHeadline=false
返回cb(空,空)
}
常量条目=数据
.toString()
.split(“;”)
常量obj={}
templateKeys.forEach((el,索引)=>{
obj[el]=条目[索引]
})
返回cb(空,obj)
})
}
const processRecord=()=>{
通过2.obj返回(函数(数据、enc、cb){
//实现您自己的处理
//此处的逻辑,例如:
专用数据
.插入(数据)
.然后(()=>cb())
.渔获量(cb)
})
}

有关此主题的更多信息,请访问Stefan Baumgartners。Stefan Baumgartners非常擅长此主题。

您可以使用流来处理大文件。 这是你需要做的。这应该很好用

npm i --save csv2json fs-extra // install the modules

const csv2json = require('csv2json');
const fs = require('fs-extra');

const source = fs.createReadStream(__dirname + '/data.csv');
const output = fs.createWriteStream(__dirname + '/result.json');
 source
   .pipe(csv2json())
   .pipe(output );

嗯。。。很多解决方案,我将添加一个:

然后

process.stdin.pipe(
    new (require("scramjet").StringStream)("utf-8")
)
    .CSVParse()
    .toJSONArray()
    .pipe(process.stdout)

这将产生您以流式方式描述的内容。

您确定没有忘记删除“所需JSON”部分中的一些大括号吗?是不是应该是
{“a”:1,“b”:2,“c”:3,“d”:4},
?噢,谢谢。谢谢。我一直在尝试
事件流
,但当它到达
es.map
时总是失败。我会坚持下去,希望能解决它。我自己还没有处理过事件流。例如,可以看看测试代码?es.split()可能不足以按行分割CSV。根据newline,如果它在双引号内,则可以是值的一部分。
npm i --save csv2json fs-extra // install the modules

const csv2json = require('csv2json');
const fs = require('fs-extra');

const source = fs.createReadStream(__dirname + '/data.csv');
const output = fs.createWriteStream(__dirname + '/result.json');
 source
   .pipe(csv2json())
   .pipe(output );
$ npm install --save scramjet
process.stdin.pipe(
    new (require("scramjet").StringStream)("utf-8")
)
    .CSVParse()
    .toJSONArray()
    .pipe(process.stdout)