NodeJS를 사용하여 CSV 파일 구문 분석
nodejs를 사용하여 10000개의 레코드로 구성된 .csv 파일을 파싱하고 각 행에 대해 몇 가지 작업을 수행하고 싶습니다.http://www.adaltas.com/projects/node-csv 을 이용해 보았습니다.행마다 이것을 멈출 수가 없었습니다.이것은 단지 10000개의 기록을 다 읽어낸 것입니다.다음 작업을 수행해야 합니다.
- CSV를 한 줄씩 읽습니다.
- 각 라인에 대해 시간 소모적인 작업 수행
- 다음 줄로 가다
누구든지 여기서 대안을 제안해 줄 수 있습니까?
fast-csv와 같은 스트림 기반 라이브러리를 사용해야 할 것 같습니다. 여기에는 검증 지원도 포함되어 있습니다.
NB! fast-csv 패키지가 적극적으로 유지되지 않아서 csv와 같은 다른 대안을 모색하고 있습니다.
나는 이런 식으로 사용했습니다:-
var fs = require('fs');
var parse = require('csv-parse');
var csvData=[];
fs.createReadStream(req.file.path)
.pipe(parse({delimiter: ':'}))
.on('data', function(csvrow) {
console.log(csvrow);
//do something with csvrow
csvData.push(csvrow);
})
.on('end',function() {
//do something with csvData
console.log(csvData);
});
현재 사용 중인 솔루션은 비동기 모듈을 사용하여 직렬로 실행합니다.
var fs = require('fs');
var parse = require('csv-parse');
var async = require('async');
var inputFile='myfile.csv';
var parser = parse({delimiter: ','}, function (err, data) {
async.eachSeries(data, function (line, callback) {
// do something with the line
doSomething(line).then(function() {
// when processing finishes invoke the callback to move to the next one
callback();
});
})
});
fs.createReadStream(inputFile).pipe(parser);
- 이 솔루션은 다음을 사용합니다.
csv-parser
에 대신에csv-parse
위의 답변들 중 일부에 사용됩니다. csv-parser
.csv-parse
.- 다 목적을 하지만, 으로는 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ을 했습니다.
csv-parser
그것을 통해 헤더를 다루기 쉽기 때문에 더 좋습니다.
csv-parser를 먼저 설치합니다.
npm install csv-parser
따라서 다음과 같은 csv-파일이 있다고 가정합니다.
NAME, AGE
Lionel Messi, 31
Andres Iniesta, 34
다음과 같이 필요한 작업을 수행할 수 있습니다.
const fs = require('fs');
const csv = require('csv-parser');
fs.createReadStream(inputFilePath)
.pipe(csv())
.on('data', function(data){
try {
console.log("Name is: "+data.NAME);
console.log("Age is: "+data.AGE);
//perform the operation
}
catch(err) {
//error handler
}
})
.on('end',function(){
//some final operation
});
자세한 내용은 다음을 참조하십시오.
주석에 언급된 바와 같이 csv-parse 대신 csv-parser를 사용할 수 있는 또 다른 장점은 다음과 같습니다.
csv-parser는 약 27KB인 반면 csv-parse는 1.6MB입니다.
fast-csv에서 스트리밍을 일시 중지하려면 다음 작업을 수행할 수 있습니다.
let csvstream = csv.fromPath(filePath, { headers: true })
.on("data", function (row) {
csvstream.pause();
// do some heavy work
// when done resume the stream
csvstream.resume();
})
.on("end", function () {
console.log("We are done!")
})
.on("error", function (error) {
console.log(error)
});
참조하는 노드 매핑 프로젝트는 CSV 데이터의 많은 부분의 각 행을 변환하는 작업을 수행하기에 충분합니다. 문서 주소: http://csv.adaltas.com/transform/ :
csv()
.from('82,Preisner,Zbigniew\n94,Gainsbourg,Serge')
.to(console.log)
.transform(function(row, index, callback){
process.nextTick(function(){
callback(null, row.reverse());
});
});
제 경험으로 볼 때, 이는 또한 상당히 빠른 구현이라고 할 수 있습니다. 거의 10,000개의 레코드를 가진 데이터 세트에서 작업해 왔으며 전체 세트에서 처리 시간은 수십 밀리초 수준이었습니다.
jurka의 스트림 기반 솔루션 제안 : node-csv IS 스트림 기반이며 Node.js의 스트리밍 API를 따릅니다.
fast-csv npm 모듈은 csv 파일에서 데이터를 줄 단위로 읽을 수 있습니다.
다음은 예입니다.
let csv= require('fast-csv');
var stream = fs.createReadStream("my.csv");
csv
.parseStream(stream, {headers : true})
.on("data", function(data){
console.log('I am one line of data', data);
})
.on("end", function(){
console.log("done");
});
var fs = require("fs");
// READ CSV INTO STRING
var data = fs.readFileSync("your.csv").toLocaleString();
// STRING TO ARRAY
var rows = data.split("\n"); // SPLIT ROWS
rows.forEach((row) => {
columns = row.split(","); //SPLIT COLUMNS
console.log(columns);
})
@는 csv 가 @Pransh Tiwari 을 이 했지만 의 했고 이 을 했지만 는 가 await
그리고.util.promisify()
. 결국 저는 csv-parser와 거의 동일하지만 약속이 있는 node-csvtojson을 만나게 되었습니다.csvtojson의 동작 사용 예는 다음과 같습니다.
const csvToJson = require('csvtojson');
const processRecipients = async () => {
const recipients = await csvToJson({
trim:true
}).fromFile('./recipients.csv');
// Code executes after recipients are fully loaded.
recipients.forEach((recipient) => {
console.log(recipient.name, recipient.email);
});
};
저는 이 간단한 것을 사용합니다: https://www.npmjs.com/package/csv-parser
사용 방법이 매우 간단합니다.
const csv = require('csv-parser')
const fs = require('fs')
const results = [];
fs.createReadStream('./CSVs/Update 20191103C.csv')
.pipe(csv())
.on('data', (data) => results.push(data))
.on('end', () => {
console.log(results);
console.log(results[0]['Lowest Selling Price'])
});
좋아요, 그래서 여기에 많은 답이 있고 제 생각과 비슷한 당신의 질문에 답을 하지 않는 것 같습니다.
데이터베이스 또는 비동기인 제3 파트 api에 연락하는 것과 같은 작업을 수행해야 합니다.너무 크거나 다른 이유로 인해 전체 문서를 메모리에 로드하지 않을 수 있으므로 처리하려면 한 줄씩 읽어야 합니다.
fs 문서를 읽었는데 읽을 때 일시 중지될 수 있지만 .on('data') 호출을 사용하면 대부분의 응답이 사용되어 문제가 발생합니다.
업데이트: Streams에 대한 정보를 그 어느 때보다 많이 알고 있습니다.
가장 좋은 방법은 쓰기 가능한 스트림을 만드는 것입니다.이렇게 하면 csv 데이터가 비동기 호출을 관리할 수 있는 쓰기 가능 스트림에 연결됩니다.파이프가 버퍼를 리더기까지 관리하므로 메모리 사용량이 너무 많아지지 않습니다.
심플 버전
const parser = require('csv-parser');
const stripBom = require('strip-bom-stream');
const stream = require('stream')
const mySimpleWritable = new stream.Writable({
objectMode: true, // Because input is object from csv-parser
write(chunk, encoding, done) { // Required
// chunk is object with data from a line in the csv
console.log('chunk', chunk)
done();
},
final(done) { // Optional
// last place to clean up when done
done();
}
});
fs.createReadStream(fileNameFull).pipe(stripBom()).pipe(parser()).pipe(mySimpleWritable)
클래스 버전
const parser = require('csv-parser');
const stripBom = require('strip-bom-stream');
const stream = require('stream')
// Create writable class
class MyWritable extends stream.Writable {
// Used to set object mode because we get an object piped in from csv-parser
constructor(another_variable, options) {
// Calls the stream.Writable() constructor.
super({ ...options, objectMode: true });
// additional information if you want
this.another_variable = another_variable
}
// The write method
// Called over and over, for each line in the csv
async _write(chunk, encoding, done) {
// The chunk will be a line of your csv as an object
console.log('Chunk Data', this.another_variable, chunk)
// demonstrate await call
// This will pause the process until it is finished
await new Promise(resolve => setTimeout(resolve, 2000));
// Very important to add. Keeps the pipe buffers correct. Will load the next line of data
done();
};
// Gets called when all lines have been read
async _final(done) {
// Can do more calls here with left over information in the class
console.log('clean up')
// lets pipe know its done and the .on('final') will be called
done()
}
}
// Instantiate the new writable class
myWritable = new MyWritable(somevariable)
// Pipe the read stream to csv-parser, then to your write class
// stripBom is due to Excel saving csv files with UTF8 - BOM format
fs.createReadStream(fileNameFull).pipe(stripBom()).pipe(parser()).pipe(myWritable)
// optional
.on('finish', () => {
// will be called after the wriables internal _final
console.log('Called very last')
})
이전 방법:
가독성 문제
const csv = require('csv-parser');
const fs = require('fs');
const processFileByLine = async(fileNameFull) => {
let reading = false
const rr = fs.createReadStream(fileNameFull)
.pipe(csv())
// Magic happens here
rr.on('readable', async function(){
// Called once when data starts flowing
console.log('starting readable')
// Found this might be called a second time for some reason
// This will stop that event from happening
if (reading) {
console.log('ignoring reading')
return
}
reading = true
while (null !== (data = rr.read())) {
// data variable will be an object with information from the line it read
// PROCESS DATA HERE
console.log('new line of data', data)
}
// All lines have been read and file is done.
// End event will be called about now so that code will run before below code
console.log('Finished readable')
})
rr.on("end", function () {
// File has finished being read
console.log('closing file')
});
rr.on("error", err => {
// Some basic error handling for fs error events
console.log('error', err);
});
}
당신은 그것을 알아차릴 것입니다.reading
flag.는 어떤 이유에서인지 큰 filesflag에서 두 . 나는 어떤 이유에서인지 파일의 끝에 있는 .on('readable')이 작고 큰 파일에서 두 번째로 호출되는 것을 알아챘습니다.왜 그런지는 모르겠지만, 이것은 같은 줄 항목을 읽는 두 번째 프로세스에서 그것을 차단합니다.
이것이 외부 url에서 csv 파일을 가져오는 나의 해결책입니다.
const parse = require( 'csv-parse/lib/sync' );
const axios = require( 'axios' );
const readCSV = ( module.exports.readCSV = async ( path ) => {
try {
const res = await axios( { url: path, method: 'GET', responseType: 'blob' } );
let records = parse( res.data, {
columns: true,
skip_empty_lines: true
} );
return records;
} catch ( e ) {
console.log( 'err' );
}
} );
readCSV('https://urltofilecsv');
사용하고 있었습니다.csv-parse
그러나 더 큰 파일의 경우 성능 문제가 발생했습니다. 제가 찾은 더 나은 라이브러리 중 하나는 Papa Parse입니다. 문서는 양호하고 지원이 좋으며 경량이며 종속성이 없습니다.
설치하다papaparse
npm install papaparse
용도:
- 비동기식/대기
const fs = require('fs');
const Papa = require('papaparse');
const csvFilePath = 'data/test.csv'
// Function to read csv which returns a promise so you can do async / await.
const readCSV = async (filePath) => {
const csvFile = fs.readFileSync(filePath)
const csvData = csvFile.toString()
return new Promise(resolve => {
Papa.parse(csvData, {
header: true,
transformHeader: header => header.trim(),
complete: results => {
console.log('Complete', results.data.length, 'records.');
resolve(results.data);
}
});
});
};
const test = async () => {
let parsedData = await readCSV(csvFilePath);
}
test()
- 콜백
const fs = require('fs');
const Papa = require('papaparse');
const csvFilePath = 'data/test.csv'
const file = fs.createReadStream(csvFilePath);
var csvData=[];
Papa.parse(file, {
header: true,
transformHeader: header => header.trim(),
step: function(result) {
csvData.push(result.data)
},
complete: function(results, file) {
console.log('Complete', csvData.length, 'records.');
}
});
메모header: true
는 구성의 옵션입니다. 기타 옵션은 문서를 참조하십시오.
라인 바이 라인 npm 플러그인을 시도합니다.
npm install line-by-line --save
약속 접근법을 사용해서 이 작업을 해봤습니다.
const fs = require('fs')
const {parse} = require('csv-parse')
function readFile(path){
return new Promise((resolve,reject)=>{
fs.readFile(path, function (err, fileData) {
parse(fileData, {columns: false, trim: true}, async function(err, rows) {
if(err){
reject(err)
}
resolve(rows)
})
})
})
}
fs = require('fs');
fs.readFile('FILENAME WITH PATH','utf8', function(err,content){
if(err){
console.log('error occured ' +JSON.stringify(err));
}
console.log('Fileconetent are ' + JSON.stringify(content));
})
csv-to-json 모듈을 사용하여 csv를 json 형식으로 변환한 후 프로그램에서 json 파일을 쉽게 사용할 수 있습니다.
csv-parse는 현재 사용 사례에 적합한 비동기 반복기를 지원합니다.
npm 설치 csv
샘플 CSV 파일 구문 분석을 위해 CSV 파일이 필요하므로 이미 파일이 있거나 아래 텍스트를 복사하여 새 파일에 붙여넣고 해당 파일을 "mycsv.csv"라고 부를 수 있습니다.
ABC, 123, Fudge
532, CWE, ICECREAM
8023, POOP, DOGS
441, CHEESE, CARMEL
221, ABC, HOUSE
1
ABC, 123, Fudge
2
532, CWE, ICECREAM
3
8023, POOP, DOGS
4
441, CHEESE, CARMEL
5
221, ABC, HOUSE
CSV 파일 읽기 및 구문 분석 샘플 코드
새 파일을 만들고 다음 코드를 삽입합니다.뒤에서 무슨 일이 일어나고 있는지 꼭 읽어보세요.
var csv = require('csv');
// loads the csv module referenced above.
var obj = csv();
// gets the csv module to access the required functionality
function MyCSV(Fone, Ftwo, Fthree) {
this.FieldOne = Fone;
this.FieldTwo = Ftwo;
this.FieldThree = Fthree;
};
// Define the MyCSV object with parameterized constructor, this will be used for storing the data read from the csv into an array of MyCSV. You will need to define each field as shown above.
var MyData = [];
// MyData array will contain the data from the CSV file and it will be sent to the clients request over HTTP.
obj.from.path('../THEPATHINYOURPROJECT/TOTHE/csv_FILE_YOU_WANT_TO_LOAD.csv').to.array(function (data) {
for (var index = 0; index < data.length; index++) {
MyData.push(new MyCSV(data[index][0], data[index][1], data[index][2]));
}
console.log(MyData);
});
//Reads the CSV file from the path you specify, and the data is stored in the array we specified using callback function. This function iterates through an array and each line from the CSV file will be pushed as a record to another array called MyData , and logs the data into the console to ensure it worked.
var http = require('http');
//Load the http module.
var server = http.createServer(function (req, resp) {
resp.writeHead(200, { 'content-type': 'application/json' });
resp.end(JSON.stringify(MyData));
});
// Create a webserver with a request listener callback. This will write the response header with the content type as json, and end the response by sending the MyData array in JSON format.
server.listen(8080);
// Tells the webserver to listen on port 8080(obviously this may be whatever port you want.)
1
var csv = require('csv');
2
// loads the csv module referenced above.
3
4
var obj = csv();
5
// gets the csv module to access the required functionality
6
7
function MyCSV(Fone, Ftwo, Fthree) {
8
this.FieldOne = Fone;
9
this.FieldTwo = Ftwo;
10
this.FieldThree = Fthree;
11
};
12
// Define the MyCSV object with parameterized constructor, this will be used for storing the data read from the csv into an array of MyCSV. You will need to define each field as shown above.
13
14
var MyData = [];
15
// MyData array will contain the data from the CSV file and it will be sent to the clients request over HTTP.
16
17
obj.from.path('../THEPATHINYOURPROJECT/TOTHE/csv_FILE_YOU_WANT_TO_LOAD.csv').to.array(function (data) {
18
for (var index = 0; index < data.length; index++) {
19
MyData.push(new MyCSV(data[index][0], data[index][1], data[index][2]));
20
}
21
console.log(MyData);
22
});
23
//Reads the CSV file from the path you specify, and the data is stored in the array we specified using callback function. This function iterates through an array and each line from the CSV file will be pushed as a record to another array called MyData , and logs the data into the console to ensure it worked.
24
25
var http = require('http');
26
//Load the http module.
27
28
var server = http.createServer(function (req, resp) {
29
resp.writeHead(200, { 'content-type': 'application/json' });
30
resp.end(JSON.stringify(MyData));
31
});
32
// Create a webserver with a request listener callback. This will write the response header with the content type as json, and end the response by sending the MyData array in JSON format.
33
34
server.listen(8080);
35
// Tells the webserver to listen on port 8080(obviously this may be whatever port you want.)
Things to be aware of in your app.js code
In lines 7 through 11, we define the function called 'MyCSV' and the field names.
If your CSV file has multiple columns make sure you define this correctly to match your file.
On line 17 we define the location of the CSV file of which we are loading. Make sure you use the correct path here.
앱을 시작하고 기능 확인 콘솔을 열고 다음 명령을 입력합니다.
Node app 1 Node app 콘솔에서 다음과 같은 출력을 볼 수 있습니다.
[ MYCSV { Fieldone: 'ABC', Fieldtwo: '123', Fieldthree: 'Fudge' },
MYCSV { Fieldone: '532', Fieldtwo: 'CWE', Fieldthree: 'ICECREAM' },
MYCSV { Fieldone: '8023', Fieldtwo: 'POOP', Fieldthree: 'DOGS' },
MYCSV { Fieldone: '441', Fieldtwo: 'CHEESE', Fieldthree: 'CARMEL' },
MYCSV { Fieldone: '221', Fieldtwo: 'ABC', Fieldthree: 'HOUSE' }, ]
1 [ MYCSV { Fieldone: 'ABC', Fieldtwo: '123', Fieldtwo: 'Fudge' }, 2 MYCSV { Fieldone: '532', Fieldtwo: 'CWE', Fieldtwo: 'ICECREAM' }, 3 MYCSV { Fieldone: '8023', Fieldtwo: 'POOP', Fieldtwo: 'DOGS' }, 4 MYCSV { Fieldone: '441', Fieldtwo: 'CHEESE', Fieldtwo: 'CARMEL' }, 5 MYCSV { Fieldtwo: '221', Fieldtwo: 'ABC', Fieldtwo: 'HOUSE' }, Fieldtwo: '221', Fieldtwo: 'ABC', Fieldtwo: 'HOUSE' }, Fieldtwo: '20', Fieldtwo: '8023', Fieldtwo: 'POOP', Fieldtwo: 'DOGS' }, Fieldtwo: '441', Fieldtwo: 'CHEESE', Fieldtwo: 'CARMEL' }, 5 MYCSV { Field] 이제 웹 브라우저를 열고 서버로 이동해야 합니다.데이터를 JSON 형식으로 출력하는 것을 봐야 합니다.
결론 node.js와 그것의 CSV 모듈을 사용하여 서버에 저장된 데이터를 빠르고 쉽게 읽고 사용할 수 있으며 요청 시 고객이 사용할 수 있도록 할 수 있습니다.
언급URL : https://stackoverflow.com/questions/23080413/parsing-a-csv-file-using-nodejs
'programing' 카테고리의 다른 글
GCC: 배열 유형에 불완전한 요소 유형이 있습니다. (0) | 2023.09.11 |
---|---|
도커: $PATH에서 실행 파일을 찾을 수 없습니다. (0) | 2023.09.11 |
Node.js REPL에 있는 함수를 )(로 호출하는 이유는 무엇입니까? (0) | 2023.09.11 |
팬더는 서로 다른 열을 가진 두 개의 데이터 프레임을 병합합니다. (0) | 2023.09.11 |
jquery $.189 jsonp (0) | 2023.09.11 |