Reading local files in JavaScript

  1. Вступ
  2. вибір файлів
  3. Вибір файлів за допомогою форми введення даних
  4. Вибір файлів за допомогою перетягування
  5. читання файлів
  6. Поділ файлу на фрагменти
  7. Контроль ходу читання

Вступ

Нарешті з'явилася можливість взаємодії з локальними файлами за допомогою HTML5. Для цього служить специфікація API файлів . Зокрема, API файлів можна використовувати для створення зменшених зображень при передачі відповідних картинок на сервер або для того, щоб додаток могло зберегти посилання на файл, якщо користувача немає в мережі. Крім того, за допомогою коду на стороні клієнта можна перевірити, чи відповідає тип MIME завантаження його розширення, або встановити обмеження за розміром.

У специфікації зазначені деякі інтерфейси для доступу до файлів в локальній файловій системі.

  1. File - окремий файл. Така інформація, як назва, розмір файлу, тип MIME і посилання на оброблювач, доступна тільки для читання.
  2. FileList - послідовність об'єктів File у вигляді масиву, що дозволяє, наприклад, реалізувати функцію <input type = "file" multiple> або перетягування папки з файлами з робочого столу.
  3. Blob - дозволяє розділити файл на фрагменти заданої величини.

У поєднанні з описаними вище структурами даних інтерфейс FileReader можна використовувати для асинхронного читання файлу за допомогою знайомих функцій обробки подій в JavaScript. Це дозволяє відстежувати процес читання, виявляти помилки і визначати, що завантаження завершено. API багато в чому нагадують модель подій XMLHttpRequest.

Примітка. На момент складання цього керівництва API, необхідні для роботи з локальними файлами, підтримувалися в браузерах Chrome 6.0 і Firefox 3.6. Починаючи з версії Firefox 3.6.3 метод File.slice () не підтримується.

вибір файлів

Спочатку перевірте, чи підтримує ваш браузер API файлів.

// Check for the various File API support. if (window.File && window.FileReader && window.FileList && window.Blob) {// Great success! All the File APIs are supported. } Else {alert ( 'The File APIs are not fully supported in this browser.'); }

Зрозуміло, якщо для роботи додатка потрібні лише деякі з цих API, скоректуйте фрагмент коду відповідним чином.

Вибір файлів за допомогою форми введення даних

Найпростіший спосіб завантаження файлів - використання стандартного елемента <input type = "file">. JavaScript повертає список обраних об'єктів File у вигляді об'єкта FileList. Ось приклад використання атрибута multiple для вибору відразу декількох файлів:

<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 ++) {output.push ( '<li> <strong>', escape (f.name), '</ strong> (', f.type || 'n / a', ') -', f.size, 'bytes, last modified:', f.lastModifiedDate.toLocaleDateString (), '</ li>'); } Document.getElementById ( 'list'). InnerHTML = '<ul>' + output.join ( '') + '</ ul>'; } Document.getElementById ( 'files'). AddEventListener ( 'change', handleFileSelect, false); </ Script>

Приклад: вибір файлів за допомогою форми введення даних. Спробуйте самі!

Вибір файлів за допомогою перетягування

Ще одним способом завантаження файлів є їх перетягування з робочого столу в браузер. Щоб включити підтримку перетягування, досить внести невеликі зміни в код з попереднього прикладу.

<Div id = "drop_zone"> Drop files here </ div> <output id = "list"> </ output> <script> function handleFileSelect (evt) {evt.stopPropagation (); evt.preventDefault (); var files = evt.dataTransfer.files; // FileList object. // files is a FileList of File objects. List some properties. var output = []; for (var i = 0, f; f = files [i]; i ++) {output.push ( '<li> <strong>', escape (f.name), '</ strong> (', f.type || 'n / a', ') -', f.size, 'bytes, last modified:', f.lastModifiedDate.toLocaleDateString (), '</ li>'); } Document.getElementById ( 'list'). InnerHTML = '<ul>' + output.join ( '') + '</ ul>'; } Function handleDragOver (evt) {evt.stopPropagation (); evt.preventDefault (); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. } // Setup the dnd listeners. var dropZone = document.getElementById ( 'drop_zone'); dropZone.addEventListener ( 'dragover', handleDragOver, false); dropZone.addEventListener ( 'drop', handleFileSelect, false); </ Script>

Приклад: вибір файлів за допомогою перетягування. Спробуйте самі!

Перетягніть сюди файли

Примітка. Деякі браузери обробляють елементи <input type = "file"> як цільові області для перетягування файлів. Спробуйте перетягнути файли в поле введення в попередньому прикладі.

читання файлів

А тепер найцікавіше.

Отримавши посилання на об'єкт File, створіть екземпляр об'єкта FileReader , Який збереже його зміст в пам'ять. Як тільки завершується завантаження, на стороні користувача викликається подія onload. Його атрибут result можна використовувати для доступу до даних у файлі.

Існує чотири методи асинхронного читання файлів за допомогою об'єкта FileReader.

  • FileReader.readAsBinaryString (Blob | File) - властивість result містить дані про файлі або його фрагменті у вигляді рядка бінарного коду. Кожен байт представлений цілим числом від 0 до 255.
  • FileReader.readAsText (Blob | File, opt_encoding) - властивість result містить дані про файлі або його фрагменті у вигляді текстового рядка. За замовчуванням використовується кодування UTF-8. Щоб задати інший формат, використовуйте необов'язковий параметр кодування opt_encoding.
  • FileReader.readAsDataURL (Blob | File) - властивість result містить дані про файлі або його фрагменті у вигляді схеми data: URL .
  • FileReader.readAsArrayBuffer (Blob | File) - властивість result містить дані про файлі або його фрагменті у вигляді об'єкта ArrayBuffer .

Якщо для об'єкта FileReader викликається один з цих методів, то хід його обробки можна відстежувати за допомогою атрибутів onloadstart, onprogress, onload, onabort, onerror і onloadend.

У прикладі нижче з виділених користувачем файлів вибираються картинки, викликається функція reader.readAsDataURL () і виводиться зменшене зображення шляхом установки для атрибута src значення, що представляє URL даних.

<Style> .thumb {height: 75px; border: 1px solid # 000; margin: 10px 5px 0 0; } </ Style> <input type = "file" id = "files" name = "files []" multiple /> <output id = "list"> </ output> <script> function handleFileSelect (evt) {var files = evt.target.files; // FileList object // Loop through the FileList and render image files as thumbnails. for (var i = 0, f; f = files [i]; i ++) {// Only process image files. if (! f.type.match ( 'image. *')) {continue; } Var reader = new FileReader (); // Closure to capture the file information. reader.onload = (function (theFile) {return function (e) {// Render thumbnail. var span = document.createElement ( 'span'); span.innerHTML = [ '<img class = "thumb" src = "' , e.target.result, ' "title ="', escape (theFile.name), ' "/>']. join ( ''); document.getElementById ( 'list'). insertBefore (span, null); };}) (f); // Read in the image file as a data URL. reader.readAsDataURL (f); }} Document.getElementById ( 'files'). AddEventListener ( 'change', handleFileSelect, false); </ Script>

Приклад: читання файлів. Спробуйте самі!

Поділ файлу на фрагменти

У деяких випадках зчитування всього файлу в пам'ять не є оптимальним варіантом. Припустимо, ви вирішили створити інструмент для асинхронної завантаження файлів. Щоб збільшити її швидкість, можна розділити файл на фрагменти однакового розміру, які будуть зчитуватися і відправлятися окремо. На сервері фрагменти будуть знову об'єднуватися в потрібному порядку.

Інтерфейс File підтримує метод slice для розбиття файлу на фрагменти. Першим аргументом цього методу є початковий байт файлу, другим - його останній байт, а третім - необов'язковий ланцюжок з описом типу змісту. Семантика цього методу недавно була змінена, і тепер необхідно використовувати префікс браузера:

if (file.webkitSlice) {var blob = file.webkitSlice (startingByte, endindByte); } Else if (file.mozSlice) {var blob = file.mozSlice (startingByte, endindByte); } Reader.readAsBinaryString (blob);

Нижче представлений код для зчитування фрагментів файлу. Зверніть увагу на те, що на місці події onload в ньому використовується подія onloadend, а також перевіряється умова evt.target.readyState.

<Style> #byte_content {margin: 5px 0; max-height: 100px; overflow-y: auto; overflow-x: hidden; } #Byte_range {margin-top: 5px; } </ Style> <input type = "file" id = "files" name = "file" /> Read bytes: <span class = "readBytesButtons"> <button data-startbyte = "0" data-endbyte = "4 "> 1-5 </ button> <button data-startbyte =" 5 "data-endbyte =" 14 "> 6-15 </ button> <button data-startbyte =" 6 "data-endbyte =" 7 "> 7-8 </ button> <button> entire file </ button> </ span> <div id = "byte_range"> </ div> <div id = "byte_content"> </ div> <script> function readBlob ( opt_startByte, opt_stopByte) {var files = document.getElementById ( 'files'). files; if (! files.length) {alert ( 'Please select a file!'); return; } Var file = files [0]; var start = parseInt (opt_startByte) || 0; var stop = parseInt (opt_stopByte) || file.size - 1; var reader = new FileReader (); // If we use onloadend, we need to check the readyState. reader.onloadend = function (evt) {if (evt.target.readyState == FileReader.DONE) {// DONE == 2 document.getElementById ( 'byte_content'). textContent = evt.target.result; document.getElementById ( 'byte_range'). textContent = [ 'Read bytes:', start + 1, '-', stop + 1, 'of', file.size, 'byte file']. join ( ''); }}; if (file.webkitSlice) {var blob = file.webkitSlice (start, stop + 1); } Else if (file.mozSlice) {var blob = file.mozSlice (start, stop + 1); } Reader.readAsBinaryString (blob); } Document.querySelector ( '. ReadBytesButtons'). AddEventListener ( 'click', function (evt) {if (evt.target.tagName.toLowerCase () == 'button') {var startByte = evt.target.getAttribute ( ' data-startbyte '); var endByte = evt.target.getAttribute (' data-endbyte '); readBlob (startByte, endByte);}}, false); </ Script>

Приклад: поділ файлу на фрагменти. Спробуйте самі!

Контроль ходу читання

Одним з переваг асинхронної обробки подій є можливість відслідковувати хід читання: це особливо зручно при роботі з великими файлами, для контролю помилок і для визначення моменту завершення читання.

Хід читання можна відстежувати за допомогою подій onloadstart і onprogress.

Нижче наведено код, що відображає рядок ходу читання. Щоб оцінити його в дії, завантажте файл, який має великий розмір або знаходиться на віддаленому носії.

<Style> #progress_bar {margin: 10px 0; padding: 3px; border: 1px solid # 000; font-size: 14px; clear: both; opacity: 0; -moz-transition: opacity 1s linear; -o-transition: opacity 1s linear; -webkit-transition: opacity 1s linear; } # Progress_bar.loading {opacity: 1.0; } #Progress_bar .percent {background-color: # 99ccff; height: auto; width: 0; } </ Style> <input type = "file" id = "files" name = "file" /> <button onclick = "abortRead ();"> Cancel read </ button> <div id = "progress_bar"> < div class = "percent"> 0% </ div> </ div> <script> var reader; var progress = document.querySelector ( '. percent'); function abortRead () {reader.abort (); } Function errorHandler (evt) {switch (evt.target.error.code) {case evt.target.error.NOT_FOUND_ERR: alert ( 'File Not Found!'); break; case evt.target.error.NOT_READABLE_ERR: alert ( 'File is not readable'); break; case evt.target.error.ABORT_ERR: break; // noop default: alert ( 'An error occurred reading this file.'); }; } Function updateProgress (evt) {// evt is an ProgressEvent. if (evt.lengthComputable) {var percentLoaded = Math.round ((evt.loaded / evt.total) * 100); // Increase the progress bar length. if (percentLoaded <100) {progress.style.width = percentLoaded + '%'; progress.textContent = percentLoaded + '%'; }}} Function handleFileSelect (evt) {// Reset progress indicator on new file selection. progress.style.width = '0%'; progress.textContent = '0%'; reader = new FileReader (); reader.onerror = errorHandler; reader.onprogress = updateProgress; reader.onabort = function (e) {alert ( 'File read cancelled'); }; reader.onloadstart = function (e) {document.getElementById ( 'progress_bar'). className = 'loading'; }; reader.onload = function (e) {// Ensure that the progress bar displays 100% at the end. progress.style.width = '100%'; progress.textContent = '100%'; setTimeout ( "document.getElementById ( 'progress_bar'). className = '';", 2000); } // Read in the image file as a binary string. reader.readAsBinaryString (evt.target.files [0]); } Document.getElementById ( 'files'). AddEventListener ( 'change', handleFileSelect, false); </ Script>

Приклад: відстеження ходу читання. Спробуйте самі!

посилання

Уважаемые партнеры, если Вас заинтересовала наша продукция, мы готовы с Вами сотрудничать. Вам необходимо заполнить эту форму и отправить нам. Наши менеджеры в оперативном режиме обработают Вашу заявку, свяжутся с Вами и ответят на все интересующее Вас вопросы.

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: