Html5 fileReader - как читать только первые N символов файла?
В настоящее время я использую шаблон, подобный следующему, чтобы прочитать первые 3 символа серии файлов:
var files = e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
var fr = new FileReader();
fr.onload = function(e) {
var first_three_chars = e.target.result.substr(0,3);
}
fr.readAsText(f);
}
Проблема в том, что меня интересуют только первые 3 символа файла, тогда как этот метод читает весь файл, тратя много памяти и времени. Как я могу быстро перебирать файлы, просто быстро заглядывая в первые символы?
Изменить: slice() был ответом, спасибо sshen. Вот как я это сделал:
var files = e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
var fr = new FileReader();
fr.onloadend = function(e) {
if (e.target.readyState == FileReader.DONE) {
var first_three_chars = e.target.result;
}
};
var blob = f.slice(0, 3);
fr.readAsText(blob);
}
Ответы
Ответ 1
Вы можете использовать метод .slice
. Вы можете прочитать здесь
var reader = new FileReader();
reader.onloadend = function(evt)
{
if (evt.target.readyState == FileReader.DONE) // DONE == 2
{
alert(evt.target.result);
}
};
var blob = file.slice(start, stop + 1);
reader.readAsBinaryString(blob);
Ответ 2
В любом случае вам все равно придется просматривать список файлов, содержимое интерфейса FileList. Причина, по которой вы читаете во всем файле, - это когда вы прикрепляете onload к каждому файлу и вызываете readAsText() Если вы не хотите читать во всем файле, просто зарегистрируйте обработчик события, который получает обратный вызов с файловым списком до файлы загружаются и проходят через него. Что-то вроде this, где вы прикрепляете к представлению формы или что-то, что ожидает получить список файлов как часть объекта события, без чтения каждого первый.
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
var fileName = f.name.substr(0,3);
output.push('<strong>', fileName, '</strong>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
Ответ 3
Недостаточно повторений, чтобы комментировать, поэтому разместите здесь несколько предупреждений о решении @Stu Blair: с Blob.slice
метода Blob.slice
вы берете байты из Blob, а не символы.
Например, это не будет работать:
const blob = new Blob(['😀'], {type: 'text/plain'});
const fr = new FileReader();
fr.readAsText(blob); // Fine, fr.result will be '😀'
fr.readAsText(blob.slice(0, 2)); // Not good, fr.result will be '��'
Вам нужно будет использовать FileReader.readAsArrayBuffer
чтобы получить байты. Если ваша кодировка что-то вроде utf-8, вам придется читать с самого начала.