Подтвердить что ты не робот

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

Ответ 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, вам придется читать с самого начала.