node.js: একটি অ্যারেতে একটি পাঠ্য ফাইল পড়ুন। (প্রতিটি লাইনে অ্যারেতে একটি আইটেম রয়েছে))


163

আমি খুব, খুব বড় ফাইলটি নোড.জেএস-তে একটি জাভাস্ক্রিপ্ট অ্যারেতে পড়তে চাই।

সুতরাং, ফাইলটি যদি এর মতো হয়:

first line
two 
three
...
...

আমি অ্যারে হবে:

['first line','two','three', ... , ... ] 

ফাংশনটি দেখতে এটির মতো হবে:

var array = load(filename); 

সুতরাং এগুলি সমস্ত স্ট্রিং হিসাবে লোড করা এবং তারপরে বিভক্ত করার ধারণাটি গ্রহণযোগ্য নয়।


এই প্রশ্নের জন্য কিছু গুরুতর সম্পাদনা এবং ক্লিনআপ প্রয়োজন। এটি বলে একটি পাঠ্য ফাইলটি অ্যারেতে পড়ুন , তবে আপনি যখন সমস্ত উত্তর এবং মন্তব্যগুলি পড়েন , তখন এর অর্থ হ'ল পাঠ্য ফাইলটি একবারে এক লাইনে পড়ুন । এই প্রশ্নের জন্য @zswang এর এখনও পর্যন্ত সেরা উত্তর রয়েছে।
জেস

হ্যাঁ, কেবল সেই ফাইলটি পড়ুন এবং প্রতিটি লাইনটিকে একটি অ্যারেতে ঠেকান
ব্লেয়ার অ্যান্ডারসন

উত্তর:


89

যদি আপনি চূড়ান্ত ডেটাটিকে একটি অ্যারেতে ফিট করতে পারেন তবে আপনি কি এটি স্ট্রিংয়ে ফিট করতে এবং এটির মতো বিভক্ত করতে পারবেন না, যেমনটি পরামর্শ দেওয়া হয়েছে? যে কোনও ক্ষেত্রে আপনি যদি একবারে ফাইলটি এক লাইনে প্রক্রিয়া করতে চান তবে আপনিও এরকম কিছু চেষ্টা করতে পারেন:

var fs = require('fs');

function readLines(input, func) {
  var remaining = '';

  input.on('data', function(data) {
    remaining += data;
    var index = remaining.indexOf('\n');
    while (index > -1) {
      var line = remaining.substring(0, index);
      remaining = remaining.substring(index + 1);
      func(line);
      index = remaining.indexOf('\n');
    }
  });

  input.on('end', function() {
    if (remaining.length > 0) {
      func(remaining);
    }
  });
}

function func(data) {
  console.log('Line: ' + data);
}

var input = fs.createReadStream('lines.txt');
readLines(input, func);

সম্পাদনা: ( ফপকিন্সের মন্তব্যের জবাবে ) আমি মনে করি (অন্তত নতুন সংস্করণে) সাবস্ট্রিং ডেটা অনুলিপি করে না তবে একটি বিশেষ স্লাইসড্রিং অবজেক্ট তৈরি করে (ভি 8 উত্স কোডটিতে তাত্ক্ষণিক দৃষ্টি থেকে)। যে কোনও ক্ষেত্রে এখানে একটি পরিবর্তন রয়েছে যা উল্লিখিত সাবস্ট্রিং এড়ায় (একটি ফাইলে পরীক্ষিত বেশ কয়েকটি মেগাবাইটের মূল্য "সমস্ত কাজ এবং কোনও খেলা জ্যাককে নিস্তেজ ছেলে" করে তোলে):

function readLines(input, func) {
  var remaining = '';

  input.on('data', function(data) {
    remaining += data;
    var index = remaining.indexOf('\n');
    var last  = 0;
    while (index > -1) {
      var line = remaining.substring(last, index);
      last = index + 1;
      func(line);
      index = remaining.indexOf('\n', last);
    }

    remaining = remaining.substring(last);
  });

  input.on('end', function() {
    if (remaining.length > 0) {
      func(remaining);
    }
  });
}

ধন্যবাদ। আপনার প্রশ্নের উত্তর দিতে: না, স্ট্রিংটি খুব বড় হবে।
চকো

7
আমি প্রায় 2MB বা তার বেশি ফাইলগুলিতে এটি চেষ্টা করেছি এবং এটি বেদনাদায়ক ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে পড়েছিল reading আমি মনে করি সমস্যাটি বাকি = টি অবশিষ্ট রয়েছে ub সাবস্ট্রিং লাইন। নোডের "ডেটা" আপনাকে একবারে অনেক কিছু দিতে পারে এবং প্রতিটি লাইনের জন্য অনুলিপিটি করা দ্রুত ও (এন ^ 2) হয়ে যায়।
ফিয়োনা হপকিন্স

@ ফিনবারের উত্তরটি আরও ভাল
rü-

442

সমলয়:

var fs = require('fs');
var array = fs.readFileSync('file.txt').toString().split("\n");
for(i in array) {
    console.log(array[i]);
}

অ্যাসিঙ্ক্রোনাস:

var fs = require('fs');
fs.readFile('file.txt', function(err, data) {
    if(err) throw err;
    var array = data.toString().split("\n");
    for(i in array) {
        console.log(array[i]);
    }
});

11
ধন্যবাদ। দুর্ভাগ্যক্রমে আমার প্রশ্নটি সম্পাদনা করতে হয়েছিল। আমি বোঝাতে চাই কিভাবে একটি বৃহত আকারের ফাইল পড়তে হয়। স্ট্রিং এ সব পড়া গ্রহণযোগ্য নয়।
চকো

1
ঠিক যেটা আমার দরকার ছিল. সহজ এবং দ্রুত।
Hcabnettek

16
আমি উইন্ডোজ তৈরি করা একটি ফাইলে এটি করতে পেলাম, আমাকে বিভক্ত করতে হয়েছিল \ r \ n তবে এটি ম্যাকসকে ভেঙে দিয়েছে; সুতরাং আরও শক্তিশালী; _আররে = স্ট্রিং.রেপ্লেস (/ \ r \ n / g, '\ n')। বিভক্ত ('\ n'); উভয়ের জন্যই কাজ করেছেন
হ্যানকক

6
+1 স্ট্যাকওভারফ্লোতে কিছু সমস্যা আছে। এখন, আমি প্রায়শই খুব বেশি দূরে স্ক্রোল করার পরে সর্বাধিক ভোট দেওয়া উত্তরগুলি পাই। এটিও এর উদাহরণ। এটির সর্বোচ্চ ভোটদান রয়েছে তবে পৃষ্ঠার নীচে অবস্থিত, এটি খুব শেষ last আমি মনে করি স্ট্যাকওভারফ্লো তাদের ক্রম অ্যালগরিদম উন্নত করতে হবে।
শাশ্বত

1
@ শাশ্বত যে প্রশ্নটি জিজ্ঞাসা করবে সে সিদ্ধান্ত নিতে পারে যে সঠিক উত্তরটি কী? এই ক্ষেত্রে, বড় ফাইলগুলির জন্য তাদের স্ট্রিমিং সমাধানের প্রয়োজন ছিল এবং পুরো ফাইলটিকে স্ট্রিংয়ে রাখা অগ্রহণযোগ্য। সত্যই, এসও এর সাথে কোনও ভুল নেই।
বৈধ

73

নোড.জেএস রিডলাইন মডিউলটি ব্যবহার করা হচ্ছে ।

var fs = require('fs');
var readline = require('readline');

var filename = process.argv[2];
readline.createInterface({
    input: fs.createReadStream(filename),
    terminal: false
}).on('line', function(line) {
   console.log('Line: ' + line);
});

1
দুঃখজনকভাবে এই সমাধানটিতে একটি সমস্যা রয়েছে: যদি ফাইলটি শেষ না হয় তবে আপনি শেষ লাইনটি পাবেন না \n! দেখুন: স্ট্যাকওভারফ্লো.com
ইয়ভেস এম।

8
নোড নির্ধারণ করেছে যে সঙ্গে \ N ইস্যু stackoverflow.com/a/32599033/3763850
Gemtastic

14

JS:

var array = fs.readFileSync('file.txt', 'utf8').split('\n');

TS:

var array = fs.readFileSync('file.txt', 'utf8').toString().split('\n');

1
উপরের TypeError: fs.readFileSync(...).split is not a functionছোঁড়াটি রোধ করতে আপনার স্টোর () এর মতো ব্যবহার করা উচিত:var array = fs.readFileSync('file.txt', 'utf8').toString().split('\n');
Qua285

11

রিডলাইন ( ডকুমেন্টেশন ) ব্যবহার করুন । এখানে একটি সিএসএস ফাইল পড়া, আইকনগুলির জন্য পার্সিং এবং জসনকে সেগুলি লেখার উদাহরণ রয়েছে

var results = [];
  var rl = require('readline').createInterface({
    input: require('fs').createReadStream('./assets/stylesheets/_icons.scss')
  });


  // for every new line, if it matches the regex, add it to an array
  // this is ugly regex :)
  rl.on('line', function (line) {
    var re = /\.icon-icon.*:/;
    var match;
    if ((match = re.exec(line)) !== null) {
      results.push(match[0].replace(".",'').replace(":",''));
    }
  });


  // readline emits a close event when the file is read.
  rl.on('close', function(){
    var outputFilename = './icons.json';
    fs.writeFile(outputFilename, JSON.stringify(results, null, 2), function(err) {
        if(err) {
          console.log(err);
        } else {
          console.log("JSON saved to " + outputFilename);
        }
    });
  });


5

একটি বাফার্ডারিডার সহ , তবে ফাংশনটি অ্যাসিঙ্ক্রোনাস হওয়া উচিত:

var load = function (file, cb){
    var lines = [];
    new BufferedReader (file, { encoding: "utf8" })
        .on ("error", function (error){
            cb (error, null);
        })
        .on ("line", function (line){
            lines.push (line);
        })
        .on ("end", function (){
            cb (null, lines);
        })
        .read ();
};

load ("file", function (error, lines){
    if (error) return console.log (error);
    console.log (lines);
});

4

আমি কেবল @ ফিনবারের দুর্দান্ত উত্তর যুক্ত করতে চাই, অ্যাসিঙ্ক্রোনাস উদাহরণে কিছুটা ঠিক করে ফেলি:

অ্যাসিঙ্ক্রোনাস:

var fs = require('fs');
fs.readFile('file.txt', function(err, data) {
    if(err) throw err;
    var array = data.toString().split("\n");
    for(i in array) {
        console.log(array[i]);
    }
    done();
});

@ ম্যাডফিসিসিস্ট, সম্পন্ন () হ'ল অ্যাসিঙ্কটি প্রকাশ করে। কল করুন।


3

এটি @ এমটিমিসের উপরের উত্তরের একটি পার্থক্য।

এটি লাইনের একটি ধারা তৈরি করে। এটি 'ডেটা' এবং 'শেষ' ইভেন্টগুলি প্রকাশ করে, আপনাকে স্ট্রিমের শেষ পরিচালনা করতে দেয়।

var events = require('events');

var LineStream = function (input) {
    var remaining = '';

    input.on('data', function (data) {
        remaining += data;
        var index = remaining.indexOf('\n');
        var last = 0;
        while (index > -1) {
            var line = remaining.substring(last, index);
            last = index + 1;
            this.emit('data', line);
            index = remaining.indexOf('\n', last);
        }
        remaining = remaining.substring(last);
    }.bind(this));

    input.on('end', function() {
        if (remaining.length > 0) {
            this.emit('data', remaining);
        }
        this.emit('end');
    }.bind(this));
}

LineStream.prototype = new events.EventEmitter;

এটি একটি মোড়ক হিসাবে ব্যবহার করুন:

var lineInput = new LineStream(input);

lineInput.on('data', function (line) {
    // handle line
});

lineInput.on('end', function() {
    // wrap it up
});

1
উদাহরণগুলির মধ্যে ইভেন্টগুলি ভাগ করে নিয়ে আপনি শেষ করবেন। var EventEmitter = require('events').EventEmitter; var util = require('util'); function GoodEmitter() { EventEmitter.call(this); } util.inherits(GoodEmitter, EventEmitter);
CTAPbIu_MABP

আপনি ঠিক কোন উদাহরণের কথা বলছেন?
oferei

1
তৈরির চেষ্টা করুন এবং var li1 = new LineStream(input1), li2 = new LineStream(input2);তারপরে প্রত্যেকের জন্য কতবার 'শেষ' চালিত হয়েছে তা গণনা করুন
CTAPbIu_MABP

এটা চেষ্টা করেছি. প্রতিটি উদাহরণের জন্য একবার 'শেষ' বরখাস্ত করা হয়েছিল। var fs = require('fs'); var input1 = fs.createReadStream('text.txt'); var ls1 = new LineStream(input1); ls1.on('data', function (line) { console.log('1:line=' + line); }); ls1.on('end', function (line) { console.log('1:fin'); }); var input2 = fs.createReadStream('text.txt'); var ls2 = new LineStream(input2); ls2.on('data', function (line) { console.log('2:line=' + line); }); ls2.on('end', function (line) { console.log('2:fin'); }); আউটপুট: পাঠ্য ফাইলের প্রতিটি লাইন প্রতিটি উদাহরণের জন্য একবার নিক্ষেপ করা হয়েছিল। তাই 'শেষ' ছিল।
oferei

2

আমার একই সমস্যা ছিল এবং আমি মডিউলটি লাইন বাই লাইন দিয়ে সমাধান করেছি

https://www.npmjs.com/package/line-by-line

কমপক্ষে আমার জন্য সিঙ্ক্রোনাস এবং অ্যাসিনক্রোনাস মোড উভয়ই কবজির মতো কাজ করে।

এছাড়াও, লাইন সমাপ্ত না করে সমাপ্ত হওয়া সমস্যাগুলি \ n বিকল্পের মাধ্যমে সমাধান করা যেতে পারে:

{ encoding: 'utf8', skipEmptyLines: false }

লাইনের সমকালীন প্রক্রিয়াজাতকরণ:

var LineByLineReader = require('line-by-line'),
    lr = new LineByLineReader('big_file.txt');

lr.on('error', function (err) {
    // 'err' contains error object
});

lr.on('line', function (line) {
    // 'line' contains the current line without the trailing newline character.
});

lr.on('end', function () {
    // All lines are read, file is closed now.
}); 

2

নোড.জেএস ভি 8 ব্যবহার করে বা তারপরে একটি নতুন বৈশিষ্ট্য রয়েছে যা সাধারণ ফাংশনটিকে অ্যাসিঙ্ক ফাংশনে রূপান্তর করে।

util.promisify

এটি একটি দুর্দান্ত বৈশিষ্ট্য। এখানে txt ফাইল থেকে 10000 সংখ্যাগুলিকে একটি অ্যারেতে পার্স করার উদাহরণ দেওয়া হয়েছে, সংখ্যাগুলিতে সংযুক্ত শৃঙ্খলা ব্যবহার করে বিপর্যয় গণনা করা।

// read from txt file
const util = require('util');
const fs = require('fs')
fs.readFileAsync = util.promisify(fs.readFile);
let result = []

const parseTxt = async (csvFile) => {
  let fields, obj
  const data = await fs.readFileAsync(csvFile)
  const str = data.toString()
  const lines = str.split('\r\n')
  // const lines = str
  console.log("lines", lines)
  // console.log("str", str)

  lines.map(line => {
    if(!line) {return null}
    result.push(Number(line))
  })
  console.log("result",result)
  return result
}
parseTxt('./count-inversion.txt').then(() => {
  console.log(mergeSort({arr: result, count: 0}))
})

1

অ্যারেতে একটি বড় ফাইল পড়তে আপনি লাইন দ্বারা লাইন পড়তে পারেন বা ভাগ করে নিতে পারেন।

পাতিপাতি পড়ুন এখানে আমার উত্তর

var fs = require('fs'),
    es = require('event-stream'),

var lines = [];

var s = fs.createReadStream('filepath')
    .pipe(es.split())
    .pipe(es.mapSync(function(line) {
        //pause the readstream
        s.pause();
        lines.push(line);
        s.resume();
    })
    .on('error', function(err) {
        console.log('Error:', err);
    })
    .on('end', function() {
        console.log('Finish reading.');
        console.log(lines);
    })
);

খণ্ড দ্বারা খণ্ড এই নিবন্ধ পড়ুন

var offset = 0;
var chunkSize = 2048;
var chunkBuffer = new Buffer(chunkSize);
var fp = fs.openSync('filepath', 'r');
var bytesRead = 0;
while(bytesRead = fs.readSync(fp, chunkBuffer, 0, chunkSize, offset)) {
    offset += bytesRead;
    var str = chunkBuffer.slice(0, bytesRead).toString();
    var arr = str.split('\n');

    if(bytesRead = chunkSize) {
        // the last item of the arr may be not a full line, leave it to the next chunk
        offset -= arr.pop().length;
    }
    lines.push(arr);
}
console.log(lines);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.