--- title: Device Storage API slug: WebAPI/Device_Storage translation_of: Archive/B2G_OS/API/Device_Storage_API ---

{{ non-standard_header() }}

{{ B2GOnlyHeader2('privileged') }}

Sumário

O Device Storage API é utilizado para acessar o sistema via Web app. Como acessar arquivos do sistema é algo sensível, e por está razão que API só libera o acesso a leitura.

Nota: Acessar o storage do device é um pouco lento devido a limitação do nível físico. Em muitos casos pode ser mais rápido usar uma base de dados IndexedDB em vez de armazenar os arquivos no storage do device.

Acessando um storage

Ponto de entrada

É possível ter acesso a uma área de storage utilizando o método, {{domxref("window.navigator.getDeviceStorage()","navigator.getDeviceStorage()")}}. Este método aceita uma string como parâmetro que representa o nome do storage que você quer acessar. O método retorna um objeto {{domxref("DeviceStorage")}} que é utilizaod para ter acesso a leitura da área do storage.

Firefox OS fornece as seguintes áreas de storage:

var pics = navigator.getDeviceStorage('pictures');

Para ser capaz de utilizar cada uma dessas áreas de storage, a app precisa solicitar no seu manifesto a permissão. Como examplo, se app precisa ter acesso a área de storage  sdcard, é necessário declarar a seguinte linha "device-storage:sdcard" para slolicitar a permissão, detro do arquivo de manifesto, conforme exemplo abaixo.

"permissions": {
  "device-storage:videos":{ "access": "readonly" },
  "device-storage:pictures":{ "access": "readwrite" }
}

Utilizando um storage

Depois que uma app tem acesso a uma área de storage, ela pode adicionar, pegar e remover arquivos desta área.

Adicionar um arquivo

Para adicionar um arquivo utilizamos os seguintes métodos {{domxref("DeviceStorage.addNamed()","addNamed")}} ou {{domxref("DeviceStorage.add()","add")}}. O primeiro método permite definir o nome do arquivo que está sendo adicionado e o segundo método gera o nome de forma automatica. Ambos os métodos são assíncronos e retorna um objeto {{domxref("DOMRequest")}} para controlar o success ou error da operação. Isto é muito importânte para acompanhar o processo de leitura e escrita de arquivos.

Aqueles dois métodos espera um {{domxref("Blob")}} como o seu primeiro parametro. Este objeto será transformado em um arquivo e armazenado em background. Quando criar o objeto {{domxref("Blob")}}, é obrigado dar um type. Este type, que é o type mime, é importânte porque algumas áreas storage tem base restrição o type:

var sdcard = navigator.getDeviceStorage("sdcard");
var file   = new Blob(["This is a text file."], {type: "text/plain"});

var request = sdcard.addNamed(file, "my-file.txt");

request.onsuccess = function () {
  var name = this.result;
  console.log('File "' + name + '" successfully wrote on the sdcard storage area');
}

// An error typically occur if a file with the same name already exist
request.onerror = function () {
  console.warn('Unable to write the file: ' + this.error);
}

Nota: Repositória em uma área de storage são implícitos. Repository in a storage area are implicit. Não é possível criar explicidamente um repositório vazio.  Se você  Se você precisar de uma estrutura de repositório é necessário ter um arquivo armazenado. Então se você precisa armazenar um arquivo bar dentro do repositório foo, você tem que usar o método {{domxref("DeviceStorage.addNamed()","addNamed")}}  com o caminho compreto para o arquivo addNamed(blob, "foo/bar"). Isto também é utilzado quando você precisa recuperar um arquivo utilizando seu nome (veja abaixo).

Como os arquivos são adicionados dentro de uma área de storage retrita, por razões de securança, o caminho do arquivo não pode começar com "/" ou "../" (e "./" é inútil).

Download de um arquivo

Download de um arquivo pode ser feito de duas maneira: usando seu nome ou por interação em uma lista inteira.

A maneira mais fácil de recuperar um arquivo é utiliznado o nome do arquivo nos métodos {{domxref("DeviceStorage.get()","get")}} e {{domxref("DeviceStorage.getEditable","getEditable")}}. O primeiro método retorna um objeto {{domxref("File")}} (que age só como uma leitura de arquivo) e o segundo retorna o objeto {{domxref("FileHandle")}} object (que permite alterar o arquivo base). Os dois métodos são assíncronos e returna um objeto {{domxref("DOMRequest")}} para manipular caso tenha success ou error.

var sdcard = navigator.getDeviceStorage('sdcard');

var request = sdcard.get("my-file.txt");

request.onsuccess = function () {
  var file = this.result;
  console.log("Get the file: " + file.name);
}

request.onerror = function () {
  console.warn("Unable to get the file: " + this.error);
}

A outra maneira de recuperar arquivos é navegando pelo conteúdo da área de storage. Temos dois métodos {{domxref("DeviceStorage.enumerate()","enumerate")}} e{{domxref("DeviceStorage.enumerateEditable()","enumerateEditable")}}. O retorno do primeiro método é os objetos {{domxref("File")}} o segunto método retorna os objetos {{domxref("FileHandle")}} . Ambos métodos são assíncrono e retorna um objeto {{domxref("DOMCursor")}} para iterar ao longo da lista de arquivos. Um {{domxref("DOMCursor")}} é nada menos que um {{domxref("DOMRequest")}} com uma função a mais para interar de forma assíncrona ao longo de uma lista de coisas (arquivos nesse caso).

var pics = navigator.getDeviceStorage('pictures');

// Let's browse all the images available
var cursor = pics.enumerate();

cursor.onsuccess = function () {
  var file = this.result;
  console.log("File found: " + file.name);

  // Once we found a file we check if there is other results
  if (!this.done) {
    // Then we move to the next result, which call the cursor
    // success with the next file as result.
    this.continue();
  }
}

cursor.onerror = function () {
  console.warn("No file found: " + this.error);
}

É possível para limitar o número de resultados, passando dois parâmetros opcionais para os métodos {{domxref("DeviceStorage.enumerate()","enumerate")}} e {{domxref("DeviceStorage.enumerateEditable()","enumerateEditable")}}.

O primeiro parâmetro pode ser uma string, que representa uma sub pasta para uma busca interna.

O segundo parâmetro pode ser um objeto com uma propriedade since, que permite liberar a pesquisa por um determinado período de tempo.

var pics = navigator.getDeviceStorage('pictures');

// Lets retrieve picture from the last week.
var param = {
  since: new Date((+new Date()) - 7*24*60*60*1000)
}

var cursor = pics.enumerate(param);

cursor.onsuccess = function () {
  var file = this.result;
  console.log("Picture taken on: " + file.lastModifiedDate);

  if (!this.done) {
    this.continue();
  }
}

Deletar um arquivo

Um arquivo pode ser removido a partir da sua área de storage, simplismente utilizando o método {{domxref("DeviceStorage.delete()","delete")}}. Este método só precisa do nome para deletar o arquivo. Como todos os outros métodos da interface {{domxref("DeviceStorage")}}, este também é assíncrono e retorna um objeto {{domxref("DOMRequest")}} para manipular os status de success ou error.

var sdcard = navigator.getDeviceStorage('sdcard');

var request = sdcard.delete("my-file.txt");

request.onsuccess = function () {
  console.log("File deleted");
}

request.onerror = function () {
  console.log("Unable to delete the file: " + this.error);
}

Informação do Storage

Além de acessar os arquivos, a área de storage fornece alguns métodos para ler facilmente algumas informações importantes.

Estaço Livre

Uma das mais umportantes informações para saber sobre o storage, é a quantidade de espaço livre para armazenamento. A interface {{domxref("DeviceStorage")}} fornece duas funções úteis dedicada ao espaço de armazenamento:

Como os dois métodos são assíncronos, eles retornam um objeto {{domxref("DOMRequest")}} para tratar os status de success ou error.

var videos = navigator.getDeviceStorage('videos');

var request = videos.usedSpace();

request.onsuccess = function () {
  // The result is express in bytes, lets turn it into megabytes
  var size = this.result / 1048576;
  console.log("The videos on your device use a total of " + size.toFixed(2) + "Mo of space.");
}

request.onerror = function () {
  console.warn("Unable to get the space used by videos: " + this.error);
}

Ouvindo alterações

Como muitas aplicações pode usar uma mesma área de storage ao mesmo tempo, por este motivo é muito útil para aplicação estar ciente de uma alteração em uma área de storage. É também útil para uma aplição que deseja executar uma ação assíncrona sem a dependência do objeto de retorno {{domxref("DOMRequest")}} por cada método da interface  {{domxref("DeviceStorage")}}.

Para esse fim, um evento {{event("change")}} é acionado cada vez que um arquivo é criado, modificado ou deletado. Este evento pode ser capturado utilizando a propriedade  {{domxref("DeviceStorage.onchange","onchange")}} ou o método {{domxref("EventTarget.addEventListener()","addEventListener()")}}. O evento pega um objeto {{domxref("DeviceStorageChangeEvent")}} que um objeto regular {{domxref("Event")}} que tem duas própriedades não obrigatórias:

var sdcard = navigator.getDeviceStorage('sdcard');

sdcard.onchange = function (change) {
  var reason = change.reason;
  var path   = change.path;

  console.log('The file "' + path + '" has been ' + reason);
}

Especificação

Não faz parte de qualquer especificação.

Compatibilidade com Browser

{{ CompatibilityTable() }}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatNo() }} {{ CompatNo() }} {{ CompatNo() }}
Feature Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatNo() }} {{ CompatNo() }} {{ CompatNo() }}

Veja também