Блог веб разработки статьи | видеообзоры | исходный код

Блог веб разработки статьи | видеообзоры | исходный код

webfanat вконтакте webfanat youtube

FileSystem api

FileSystem api

Всем привет! Наконец я освободился от всех насущных дел и готов продолжать радовать вас своими статьями по веб программированию.

Тема сегодняшней статьи FileSystem api. Думаю все об этом слышали, но мало кто пробовал работать с данным api из за его слабой поддержки в браузерах. На данный момент FileSystem api поддерживается только в браузере google chrome. Но даже не смотря на это, я все равно расcкажу и покажу как с ним работать, так как это довольно интересный api появившийся вместе со стандартами html5. С данной статьи я начну доносить до вас информацию в новом формате. Надеюсь вы оцените! Поехали!

Для того чтобы начать работать с fileSystem Api проверим его поддержку в браузере! Для этого выполним такой код:

if(window.webkitRequestFileSystem){
	console.log("fileSystem api  поддерживается!");
}else{
	console.log("fileSystem api не поддерживается!");
}

Здесь мы обращаемся к fileSystem api используя специальный префикс webkit, как я уже писал на данный момент поддержка осуществлена только в браузере google chrome.

window.webkitRequestFileSystem

Это главный объект для работы с fileSystem api. Убедившись что все поддерживается переходим к работе.

Нам понадобится сервер, можно использовать локальный. Стоит отметить что файловая система формируется для каждого домена. То есть вы не сможете обмениваться данными из файловых систем с разными доменами. Это те же самые ограничения что для cookie и localStorage.

Обращаемся к файловой системе, получаем все папки и файлы из корневой директории filesystem.

function error(err){
    console.log(err);
  }

  function success(file){
    var fileSystem = file.root.createReader();
      fileSystem.readEntries (function(results) {
        console.log(results);
    });

  }

window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, success, error);

После выполнения данного кода в консоль браузера будет выведен массив со всеми папками и файлами системы. Сейчас пока у нас в файловой системе ничего не записано, поэтому выведется пустой массив. Данная конструкция:

window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, success, error);

будет фигурировать во всех операциях. В качестве первого аргумента идет window.TEMPORARY - это ключ (type) доступность хранилища файлов. Здесь также может приниматься значение window.PERSISTENT.

window.TEMPORARY - ключ при котором данные могут удаляться по усмотрению браузера, если к примеру не будет хватать места.

window.PERSISTENT - ключ при котором данные удаляются только с разрешения пользователя ресурса, здесь нужны дополнительные настройки квоты.

Я разберу работу только с ключом window.TEMPORARY! Ключ PERSISTENT оставлю вам в качестве домашнего задания.

Второй аргумент (1024*1024) - это размер необходимой памяти (в байтах) для нашей файловой системы.

Последние два аргумента функции:

success - при успешной отработке

error - функция для вывода ошибок в консоль

Нас интересует функция success. Здесь с помощью данной строчки

var fileSystem = file.root.createReader();

мы в переменную fileSystem получаем корневую директорию файловой системы и затем с помощью метода readEntries считываем файлы.

По итогу нам возвращается массив данных. Отлично, идем дальше!

Рассмотрим создание файлов в filesystem. Для удобства работы, я на каждую операцию буду создавать свою функцию.

function createFile(name, content, type){
    window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(file){
            var strblob = new Blob([content], {
                  type: type
              });
              file.root.getFile(name, {create: true}, function(fileEntry) {
                    fileEntry.createWriter(function(fileWriter) {
                        fileWriter.write(strblob);
                        console.log(fileEntry.toURL());
                  }, error);
                },error);
            }, error);
}

createFile("test.html", "<h1>Секретная страница fileSystem api! Тссс...</h1>", "text/html");

В данном примере я создал функцию при вызове которой в файловой системе будут создаваться файл test.html с содержимым "Секретная страница fileSystem api! Тссс..." и в консоль выводится ссылка на файл. Как видите она принимает три аргумента:

- название файла

- содержимое файла

- тип файла

Тип файла нужен для преобразования строки в объект blob, именно в таком формате происходить запись содержимого файла.

Для создания файла используется метод getFile() и в качестве его аргументов идут:

- название файла

- объект с опциями, для создания файла обязательно нужно указывать ключ create со значением true.

- функции обратного вызова, успешное выполнение и ошибка

При успешной отработке будет создан файл и возвращена на него ссылка fileEntry, дальше можно будет делать запись данных.

Делается это при помощи метода createWriter(), мы открываем файл на запись, получаем объект fileWriter и с помощью метода write() записываем данные в формате blob.

Также с помощью метода toURL() можно получить прямую ссылку на файл. В результате должно получится, так:

После выполнения функции createFile() мы создали файл test.html и получили очень странную на первый взгляд ссылку filesystem:http://filesystemapi/temporary/test.html где

http://filesystemapi - мой локальный хост или домен. То есть для того чтобы получить доступ к файлам filesystem api нам необходимо перейти по ссылке такого типа filesystem:{ваш домен}/temporary/{путь к файла}. Обратите внимание что при повторной проверке файловой системы в массиве появится объект нашего файла.

Допустим мы хотим переименовать наш файл test.html в hello.html, для этого создаем функцию:

function rename(path, name){
  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
      fs.root.getFile(path, {}, function(fileEntry) {
           fileEntry.moveTo(fs.root, name);
           console.log('Файл' + path + ' успешно переименован в ' + name);
        }, error);
  }, error);
}
rename("test.html", "hello.html");

После выполнения этой функции rename файл test.html будет переименован в hello.html

Первым аргументом функция принимает название файла или путь до него, а вторым новое имя.

Заметьте что и здесь мы используем метод getFile(), только уже без опций. К возвращаемому объекту fileEntry применяется метод moveTo(), который прежде всего предназначается для перемещения файлов и папок. Его работу по предназначению мы еще сегодня рассмотрим.

Переходим к чтению файлов:

function readFile(name){
  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(file){
		file.root.getFile(name, {}, function(fileEntry) {
              fileEntry.file(function(read) {
                    var reader = new FileReader();
                     reader.onloadend = function(e) {
                        console.log(this.result);
                      }
                    reader.readAsText(read)

              }, error);
            },error);
	}, error);
}
readFile("hello.html");

C помощью данной функции readFile() вы без труда прочитаете текстовый файл. Функция принимает один аргумент - название файла. После получения файла в объект fileEntry для чтения мы используем метод file(). Стоит отметить что информация также возвращается в формате blob, поэтому для ее преобразование в текстовое представление используется fileReader из file api.

В результате в консоли выводится содержимое файла!

Поcмотрим как удаляются файлы:

function removeFile(name){
  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
      fs.root.getFile(name, {create: false}, function(fileEntry) {
          fileEntry.remove(function() {
            console.log('Файл '+ name+' удален!');
          }, error);

      }, error);
  }, error);
}
removeFile("hello.html");

Для того чтобы удалить файл достаточно к объекту fileEntry применить метод remove(), результат вы увидите сами:

После вызова функции removeFile(), наш файл hello.html был успешно удален из файлового хранилища. Сама функция принимает единственный аргумент - путь к файлу.

Если мы захотим что то записать или дописать в созданный файл, можно воспользоваться моей специально разработанной функцией:

function writeFile(name, content, type, flag=false){
  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(file){
		file.root.getFile(name, {create: false}, function(fileEntry) {
				fileEntry.file(function(read) {
                    var reader = new FileReader();
                     reader.onloadend = function(e) {

                    if(!flag){
                      content = this.result + content;
                    }else{
                      removeFile(name);
                    }

                    createFile(name, content,type);
                  }
                    reader.readAsText(read)

              }, error);
            },error);


    }, error);
}

Функция использует все те функции которые мы описали выше и принимает четыре аргумента:

- путь к файлу

- Записываемые данные

- Формат данных

- Флаг, false(по умолчанию) - данные дописываются в файл, true - данные перезаписывают файл.

Вот пример работы c функцией:

Здесь вначале я создаю новый файл test.txt с записью "hello", затем используя функцию writeFile() записываю новые данные в файл.

Рассмотрим создание и удаление директорий в файловом хранилище.

function createFolder(name){
  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
    fs.root.getDirectory(name, {create: true}, function(dirEntry) {
      console.log("Папка "+name+ " Создана!");
    }, error);
  }, error);
}
createFolder("myFolder");

С помощью функции createFolder() мы создадим папку "myFolder" в нашей файловой системе:

Заметьте что теперь вместо метода getFile() мы используем getDirectory(). Этот метод служит для получения папок файловой системы. Здесь также необходимо передать в опции ключ create со значением true.

Для удаления папки:

function removeFolder(name){
  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
    fs.root.getDirectory(name, {}, function(dirEntry) {
        dirEntry.removeRecursively(function() {
            console.log('папка '+name+ ' удалена!');
          }, error);
    }, error);
  }, error);
}
removeFolder("myFolder");

После вызова функции removeFolder() указанная папка будет удалена:

Для удаления к объекту папки dirEntry применяется метод removeRecursively(). Это метод служит для рекурсивного удаления, то есть все что будет в папке также удалится.

Последние две операции которые мы рассмотрим будут перемещение и копирование файлов!

Здесь сначала я создаю папку "myFolder". Затем файл test.txt перемещаю в папку "myFolder" с помощью функции moveFile().

function moveFile(path, path2){
  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
      fs.root.getFile(path, {}, function(fileEntry) {
            fs.root.getDirectory(path2, {}, function(dirEntry) {
                fileEntry.moveTo(dirEntry);
            }, error);
        }, error);
  }, error);
}

Эта функция принимает два аргумента путь до файла который нужно переместить и путь куда переместить. Для объекта файла fileEntry применяется метод moveTo() которому в свою очередь передается объект папки куда будет перемещен файл.

После перемещения я выполняю функцию копирования:

function copyFile(path, path2){
  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
      fs.root.getFile(path, {}, function(fileEntry) {
            fs.root.getDirectory(path2, {}, function(dirEntry) {
                fileEntry.copyTo(dirEntry);
            }, error);
        }, error);
  }, error);
}

Здесь различия только в методах. Вместо moveTo() используется метод copyTo().

В завершении данной статьи рассмотрим загрузку файлов и в качестве практического примера напишем загрузчик картинок галереи.

Вот общий код:

<input type="file" id="uploadImage"/>
<div class="gallery"></div>
<script>
  function error(err){
    console.log(err);
  }

  function success(file){
    var fileSystem = file.root.createReader(),span;
      fileSystem.readEntries (function(results) {
        for(var i = 0; i < results.length; i++){
            if(results[i]['name'].search(/\.png$/) !== -1 || results[i]['name'].search(/\.gif$/) !== -1 || results[i]['name'].search(/\.jpg$/) !== -1){
              span = document.createElement('span');
              span.innerHTML = "<img width='200' src='filesystem:"+document.location.protocol+"//"+document.domain+"/temporary/"+results[i]['name']+"'/>";
              span.innerHTML += "<button onclick='deletes_fun(\""+results[i]['name']+"\")'>Удалить</button>";
              document.querySelector('.gallery').appendChild(span);

          }
        }
    });
}

function deletes_fun(name){
    window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
        fs.root.getFile(name, {}, function(fileEntry) {
            fileEntry.remove(function() {
                document.location = document.location.href;
            }, error);

        }, error);
    }, error);
}


document.querySelector("#uploadImage").addEventListener('change', function(e){
  var files = this.files;
  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024*30, function(fs) {
      for (var i = 0, file; file = files[i]; ++i) {
        (function(f) {
          if(file.name.search(/\.png$/) !== -1 || file.name.search(/\.gif$/) !== -1 || file.name.search(/\.jpg$/) !== -1){

                  fs.root.getFile(file.name, {create: true}, function(fileEntry) {
                      fileEntry.createWriter(function(fileWriter) {
                          fileWriter.write(f);
                          document.location = document.location.href;
                          }, error);
                  }, error);
          }else{
              alert('Разрешена загрузка файлов следующих форматов: png, gif, jpg');

          }
        })(file);
      }
  }, error);
});

  window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, success, error);
</script>

Здесь мы сделали возможность загрузки изображений в форматах png, jpg и gif прямо в файловое хранилище браузера и теперь картинки будут хранится в нашей файловой системе. Для удаления изображений из хранилища достаточно нажать кнопку удалить.

Вот демонстрация:

Вы можете загружать в файловое хранилище не только картинки но и любые другие файлы(аудио, текстовые) в общем все то что поддерживает браузер google chrome.

На этом данная статья подошла к концу. Подводя итог, скажу. Не смотря на то что filesystem api поддерживается только в google chrome, вам ничто не мешает пользоваться им при написании расширений для браузера chrome. Лично я так и делаю, все очень крутое но поддерживается только в google chrome я использую в своих расширениях.

Вот пример, моего расширения с использованием filesystem api -

https://chrome.google.com/webstore/detail/аудио-плеер/pmgimfodfkeiokcjdgiclpigddakahnb/related?hl=ru

. Скачивайте и наслаждайтесь!

Не забывайте подписываться на мою группу в Вконтакте и канал на youtube . Оцените новый формат подачи! С вами был Грибин Андрей, всем удачи и до скорых встреч!

Оцените статью:

Статьи

Комментарии

Внимание!!! Комментарий теперь перед публикацией проходит модерацию

Все комментарии отправлены на модерацию

Реклама

Запись экрана

Данное расширение позволяет записывать экран и выводит видео в формате webm