@Ivan_korolev

Как корректно считать кусками файл в UTF8 из под node.js?

Читаю файл построчно и гружу в массив list строки.
Сам файл может разрастись где-то до 2GB, а то и больше, не хотелось бы читать его целиком в память.

function rf2m(path){
	var handle=fs.openSync(path, 'r');
	var list=[], n=[], sdata='';
	do{	
		n=fs.readSync(handle, 10, null, 'utf8'); 
		sdata+=n[0]; //Дописываем к данным то, что получили после последнего '\n'
		var x=sdata.split("\n"); //Разбиваем данные на строки
		sdata=x[x.length-1]; //Пишем в переменную то, что получили после последнего '\n'
		for(var i=0; i<x.length-1;i++){
			list.push(x[i]);
			//fs.writeFileSync('log.txt', x[i]+"\n", {flag:'a'},'binary');
		}	 
		if(n[1]==0){ //Если длинна порции равна нулю
			if(x[x.length-1]!='') list.push(x[x.length-1]);
			break;
		}	
	}while(true)
	fs.closeSync(handle);
	return list;
}


Когда есть русские символы, я на выходе получаю нечто типо:
[OP]Се��гей
Инфо
��
[OP]Сергей
��нфо

В UTF8 русские символы занимают 2байта, а латиница - 1. Как решить эту проблему?
  • Вопрос задан
  • 3029 просмотров
Решения вопроса 2
printf
@printf
Ем детей.
А вот эта https://github.com/jahewson/node-byline штука работает корректно?

По-хорошему надо считывать байты (Buffer), а не строки, тогда не будет ломаться ничего. А в строку превращать непосредственно перед использованием.
Ответ написан
Комментировать
@Aves
И где только удалось откопать такую форму применения fs.read ?..
Read читает байты, поэтому читать надо в буфер, и потом преобразовывать с помощью StringDecoder:
var fs = require('fs');
var fd = fs.openSync('./text', 'r');
var decoder = new (require('string_decoder').StringDecoder)();
var buf = new Buffer(10);
var list = [], str, bytesReaded;

while (bytesReaded = fs.readSync(fd, buf, 0, 10, null)) {
    str = (list.pop() || '') + decoder.write(buf.slice(0, bytesReaded));
    list = list.concat(str.split("\n"));
}
console.log(list);

А лучше для таких вещей использовать потоки, если указать кодировку, будет читаться нужное количество символов, а не байт:
var fs = require('fs');
var list = [];
fs.createReadStream('./text', {encoding: 'utf8'})
    .on('readable', function() {
        var str, chunk;
        while (chunk = this.read(10)) {
            str = ((list.pop() ||'') + chunk);
            list = list.concat(str.split('\n'));
        }
        list[list.length-1] += (this.read() || '');
    })
    .on('end',function() {
        console.log(list);
    });
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
scapp
@scapp
JS фрилансер
"я на выходе получаю нечто" на каком выходе поподробнее
n=fs.readSync(handle, 10, null, 'utf8');
если сделать console.error(n) уже есть проблема кодировки или нет
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Искра Екатеринбург
от 80 000 до 100 000 ₽
Art gorka Санкт-Петербург
от 60 000 ₽
24 апр. 2024, в 19:18
50000 руб./за проект
24 апр. 2024, в 19:05
15000 руб./за проект
24 апр. 2024, в 18:39
80000 руб./за проект