Ответ 1
Ваше приложение не работает для больших файлов, потому что перед его обработкой вы читаете полный файл в памяти. Эта неэффективность может быть решена путем потоковой передачи файла (чтение фрагментов небольшого размера), поэтому вам нужно только сохранить часть файла в памяти.
A File
object также является экземпляром Blob
, который предлагает метод .slice
для создания меньшего представления файла.
Вот пример, который предполагает, что вход ASCII (demo: http://jsfiddle.net/mw99v8d4/).
function findColumnLength(file, callback) {
// 1 KB at a time, because we expect that the column will probably small.
var CHUNK_SIZE = 1024;
var offset = 0;
var fr = new FileReader();
fr.onload = function() {
var view = new Uint8Array(fr.result);
for (var i = 0; i < view.length; ++i) {
if (view[i] === 10 || view[i] === 13) {
// \n = 10 and \r = 13
// column length = offset + position of \r or \n
callback(offset + i);
return;
}
}
// \r or \n not found, continue seeking.
offset += CHUNK_SIZE;
seek();
};
fr.onerror = function() {
// Cannot read file... Do something, e.g. assume column size = 0.
callback(0);
};
seek();
function seek() {
if (offset >= file.size) {
// No \r or \n found. The column size is equal to the full
// file size
callback(file.size);
return;
}
var slice = file.slice(offset, offset + CHUNK_SIZE);
fr.readAsArrayBuffer(slice);
}
}
Предыдущий фрагмент подсчитывает количество байтов перед разрывом строки. Подсчет количества символов в тексте, состоящем из многобайтовых символов, несколько сложнее, потому что вам приходится учитывать возможность того, что последний байт в куске может быть частью многобайтового символа.