NodeJS का उपयोग करके CSV फ़ाइल पार्स करना


125

नोडज के साथ मैं 10000 रिकॉर्ड की एक .csv फ़ाइल पार्स करना चाहता हूं और प्रत्येक पंक्ति पर कुछ ऑपरेशन करता हूं। मैंने http://www.adaltas.com/projects/node-csv का उपयोग करने की कोशिश की । मैं प्रत्येक पंक्ति में विराम देने के लिए इसे प्राप्त नहीं कर सका। यह सिर्फ सभी 10000 रिकॉर्ड के माध्यम से पढ़ता है। मुझे निम्नलिखित करने की आवश्यकता है:

  1. सीएसवी लाइन को लाइन से पढ़ें
  2. प्रत्येक लाइन पर समय लेने वाला ऑपरेशन करें
  3. अगली पंक्ति पर जाएं

क्या कोई कृपया यहां कोई वैकल्पिक विचार सुझा सकता है?


शायद यह आपकी मदद करेगा: stackoverflow.com/a/15554600/1169798
सिरको

1
क्या आपने प्रत्येक पंक्ति के लिए कॉलबैक जोड़े हैं? अन्यथा यह सिर्फ उन सभी को अतुल्यकालिक रूप से पढ़ने जा रहा है।
बेन फॉर्च्यून

जवाबों:


81

ऐसा लगता है कि आपको कुछ स्ट्रीम आधारित समाधान का उपयोग करने की आवश्यकता है, पहले से ही ऐसे पुस्तकालय मौजूद थे ताकि खुद को सुदृढ़ करने से पहले, इस पुस्तकालय का प्रयास करें, जिसमें सत्यापन समर्थन भी शामिल है। https://www.npmjs.org/package/fast-csv


27
NodeCSV भी अच्छी तरह से समर्थित है और अधिक उपयोगकर्ताओं के परिमाण के लगभग एक क्रम के लिए होता है। npmjs.com/package/csv
स्टीमपॉवर

4
तेज-सीएसवी तेज, प्रयोग करने में आसान और आरंभ करने में आसान है।
रोजर गारज़ोन नीटो

1
क्या यह यूआरएल के साथ समर्थन करता है?
डीएमएस-केएच

57

मैं इस तरह से इस्तेमाल किया:

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);
    });

2
मैं कुछ गलत कर रहा हूं, लेकिन जब मैं इसे चलाता हूं, parseतो इसे परिभाषित नहीं किया जाता है। क्या मुझे कुछ याद आ रहा है? जब मैं चलता हूं npm install csv-parseऔर फिर अपने कोड ऐड में var parse = require("csv-parse");, तब यह काम करता है। क्या आपको यकीन है कि आपका काम करता है? किसी भी तरह से, मैं इस समाधान से प्यार करता हूं (भले ही मुझे csv-parseमॉड्यूल को शामिल करना है
इयान

1
आप सही @lan हैं, इसमें csv-parseमॉड्यूल शामिल होना चाहिए ।
विनीत

1
बहुत बढ़िया, आपका जवाब सत्यापित करने और अपडेट करने के लिए धन्यवाद!
इयान

3
अच्छा समाधान है। मेरे लिये कार्य करता है।
सूर्य मधुमक्खी

3
दुख की बात है कि यह बुरा है - मुझे भारी फ़ाइलों और लंबी लाइनों के साथ त्रुटियां हुईं .... (मेमोरी त्रुटियां - हालांकि इसे पढ़ने के अन्य तरीके - काम करता है)
सेटी

55

मेरा वर्तमान समाधान श्रृंखला में निष्पादित करने के लिए एसिंक्स मॉड्यूल का उपयोग करता है:

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);

1
मुझे लगता है कि आपको कुछ ') याद है?'
स्टीवन लुओंग सी

मुझे लगता है कि लाइनों 14 और 15 के अंत में एक ') जोड़ने से समस्या को ठीक करना चाहिए।
जॉन

@ शशांकविवेक - इस पुराने उत्तर में (2015 से), 'async' एक npm लाइब्रेरी है जिसका उपयोग किया जाता है। इसके बारे में अधिक यहाँ पर caolan.github.io/async - यह समझने के लिए कि शायद यह ब्लॉग की मदद क्यों करता है। risingstack.com/node-hero-async-programming-in-node-js लेकिन जावास्क्रिप्ट 2015 से बहुत विकसित हुई है, और यदि आपका प्रश्न है सामान्य रूप में async के बारे में अधिक है, तो यह और अधिक हाल के लेख पढ़ने के लिए है medium.com/@tkssharma/...
prule

15
  • यह समाधान ऊपर दिए गए कुछ उत्तरों में उपयोग किए जाने के csv-parserबजाय उपयोग करता csv-parseहै।
  • csv-parserकरीब 2 साल बाद आया csv-parse
  • दोनों एक ही उद्देश्य को हल करते हैं, लेकिन व्यक्तिगत रूप से मैं csv-parserबेहतर पाया गया हूं , क्योंकि इसके माध्यम से हेडर को संभालना आसान है।

पहले csv-parser स्थापित करें:

npm install csv-parser

तो मान लीजिए कि आपके पास इस तरह एक सीएसवी-फाइल है:

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
});  

आगे पढ़ने के लिए देखें


13

तेज़-सीएसवी में स्ट्रीमिंग को रोकने के लिए आप निम्नलिखित कार्य कर सकते हैं:

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)
    });

csvstream.pause () और फिर से शुरू () वही है जो मैं ढूंढ रहा हूं! मेरे एप्लिकेशन हमेशा मेमोरी से बाहर चलेंगे क्योंकि यह डेटा को बहुत तेजी से पढ़ता है जो इसे प्रोसेस कर सकता है।
एहरहार्ट

@adnan ने इसे इंगित करने के लिए धन्यवाद दिया। यह प्रलेखन में उल्लेख नहीं किया गया है और यही मैं भी देख रहा था।
पीयूष बेली

10

नोड-सीएसवी प्रोजेक्ट जिसे आप संदर्भित कर रहे हैं, सीएसवी डेटा के एक बड़े हिस्से की प्रत्येक पंक्ति को डॉक्स से: 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());
    });
});

अपने अनुभव से, मैं कह सकता हूं कि यह भी एक तेजी से कार्यान्वयन है, मैं इसके साथ 10k रिकॉर्ड के साथ डेटा सेट पर काम कर रहा हूं और प्रसंस्करण समय पूरे सेट के लिए एक उचित दसियों-मिली-सेकंड स्तर पर था।

जुर्का की स्ट्रीम आधारित समाधान सुझाव का पालन करना: नोड- csv आईएस स्ट्रीम आधारित है और Node.js की स्ट्रीमिंग API का अनुसरण करता है।


8

तेजी से सीएसवी 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");
 });

1
fast-csv@4.0.2 में कोई भी नहीं है fromStream()और इसकी परियोजना स्थल में उदाहरणों और प्रलेखन का अभाव है।
Cees टिम्मरमैन

3

मुझे एक async सीएसवी रीडर की आवश्यकता थी और मूल रूप से @Pransh तिवारी के उत्तर की कोशिश की, लेकिन यह साथ काम नहीं कर सका awaitऔर util.promisify()। आखिरकार मैं नोड- 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);
    });
};

2

लाइन द्वारा लाइन की कोशिश करो npm प्लगइन।

npm install line-by-line --save

5
प्लगइन स्थापित करना सवाल नहीं था जो पूछा गया था। प्लगइन का उपयोग करने के तरीके और / या यह बताने के लिए कि ओपी का उपयोग क्यों करना चाहिए, यह बताने के लिए कुछ कोड जोड़कर यह कहीं अधिक फायदेमंद होगा।
डोमडम्ब्रोगिया

2

यह बाहरी यूआरएल से सीएसवी फ़ाइल प्राप्त करने के लिए मेरा समाधान है

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');

2

प्रतीक्षा / async के साथ इस कार्य को करने के लिए समाधान :

const csv = require('csvtojson')
const csvFilePath = 'data.csv'
const array = await csv().fromFile(csvFilePath);

2

ठीक है तो यहाँ कई उत्तर हैं और मुझे नहीं लगता कि वे आपके प्रश्न का उत्तर देते हैं जो मुझे लगता है कि मेरे समान है।

आपको एक डेटाबेस या तीसरे भाग एपी से संपर्क करने जैसा एक ऑपरेशन करने की आवश्यकता है जो समय लगेगा और एसिंक्रोनस है। आप बड़े या किसी अन्य कारण से पूरे दस्तावेज़ को मेमोरी में लोड नहीं करना चाहते हैं इसलिए आपको लाइन टू प्रोसेस द्वारा लाइन को पढ़ने की आवश्यकता है।

मैंने fs दस्तावेज़ों में पढ़ा है और यह पढ़ने पर विराम लगा सकता है लेकिन .on ('डेटा') कॉल का उपयोग करने से यह निरंतर हो जाएगा जो इनमें से अधिकांश उत्तर का उपयोग करते हैं और समस्या का कारण बनते हैं।


अद्यतन: मैं स्ट्रीम के बारे में अधिक जानकारी जानता हूं कि मैं कभी चाहता था

ऐसा करने का सबसे अच्छा तरीका एक लेखन स्ट्रीम बनाना है। यह सीएसवी डेटा को आपके लेखन स्ट्रीम में पाइप करेगा जिसे आप एसिंक्रोनस कॉल का प्रबंधन कर सकते हैं। पाइप पाठक को सभी तरह से बफर का प्रबंधन करेगा ताकि आप भारी मेमोरी उपयोग के साथ हवा न दें

सरल संस्करण

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ध्वज दिखाई देगा । मैंने देखा है कि किसी कारण से फ़ाइल के अंत में .on ('पठनीय') छोटी और बड़ी फ़ाइलों पर दूसरी बार कॉल किया जाता है। मैं अनिश्चित क्यों हूं, लेकिन यह एक ही पंक्ति वस्तुओं को पढ़ने वाली दूसरी प्रक्रिया से अवरुद्ध है।


1

मैं इस सरल का उपयोग करता हूं: 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'])
  });

1

मैं उपयोग कर रहा था, csv-parseलेकिन बड़ी फ़ाइलों के प्रदर्शन के मुद्दों में चल रहा था एक बेहतर पुस्तकालयों में से एक मैंने पाया है पापा पारसे , डॉक्स अच्छे हैं, अच्छा समर्थन, हल्के, कोई निर्भरता नहीं है।

इंस्टॉल papaparse

npm install papaparse

उपयोग:

  • async / प्रतीक्षा करें
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कॉन्फ़िगरेशन पर एक विकल्प है, अन्य विकल्पों के लिए डॉक्स देखें


0
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));
})

0

आप csv-to-json मॉड्यूल का उपयोग करके csv को json फॉर्मेट में बदल सकते हैं और फिर आप आसानी से अपने प्रोग्राम में json फाइल का उपयोग कर सकते हैं


-1

npm सीएसवी स्थापित करें

नमूना 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.

अपना एप्लिकेशन प्रारंभ करें और कार्यक्षमता सत्यापित करें एक कंसोल खोलें और निम्न कमांड टाइप करें:

नोड ऐप 1 नोड ऐप आपको अपने कंसोल में निम्न आउटपुट देखना चाहिए:

[  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', Fieldthree: 'Fudge'}, 2 MYCSV {Fieldone: '532', Fieldtwo: 'CWE', Fieldthree: 'ICECREAM'}, 3 MYCSV {Fieldone: '8023', फील्डट्वो: 'पीओपी', फील्डथ्री: 'डीओजीएस'}, 4 एमसीसीएसवी {फील्डऑन: '441', फील्डट्वो: 'शेमस', फील्डथ्री: 'कार्मेल'} ", 5 MYCSV {फील्डऑन: '221', फील्डट्वो: 'ABC', फील्डथ्री: 'HOUSE'},] अब आपको एक वेब-ब्राउज़र खोलना चाहिए और अपने सर्वर पर नेविगेट करना चाहिए। आपको इसे JSON प्रारूप में डेटा आउटपुट करना चाहिए।

निष्कर्ष नोड.जेएस का उपयोग करना और यह सीएसवी मॉड्यूल है जो हम सर्वर पर संग्रहीत डेटा को जल्दी और आसानी से पढ़ सकते हैं और उपयोग कर सकते हैं और इसे ग्राहक के लिए उपलब्ध करा सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.