Este complemento implementa una API de archivos que permite el acceso de lectura/escritura a los archivos que residen en el dispositivo.
Este complemento se basa en varias especificaciones, que incluyen: La API de archivos HTML5 http://www.w3.org/TR/FileAPI/
También implementa la especificación FileWriter: http://dev.w3.org/2009/dap/file-system/file-writer.html
Este complemento define un objeto global. webtoappx.file
Aunque el objeto está en el ámbito global, no está disponible para las aplicaciones hasta después de que deviceready
se activa el evento.
document.addEventListener("deviceready", onDeviceReady, false); function onDeviceReady() { console.log(webtoappx.file); }
Where to Store Files
Cada URL tiene el formato file:///path/to/spot/
y se puede convertir a un DirectoryEntry
formato window.resolveLocalFileSystemURL()
.
webtoappx.file.applicationDirectory
– Directorio de solo lectura donde está instalada la aplicación.webtoappx.file.applicationStorageDirectory
– Directorio raíz del sandbox de la aplicación. Todos los datos contenidos dentro son privados para la aplicación.webtoappx.file.dataDirectory
– Almacenamiento de datos persistentes y privados dentro del entorno limitado de la aplicación usando la memoria interna (si necesita usar memoria externa, usewebtoappx.file.externalDataDirectory
).webtoappx.file.cacheDirectory
– Directorio para archivos de datos almacenados en caché o cualquier archivo que su aplicación pueda recrear fácilmente. El sistema operativo puede eliminar estos archivos cuando el dispositivo se queda sin almacenamiento; sin embargo, las aplicaciones no deben depender del sistema operativo para eliminar archivos aquí.webtoappx.file.externalApplicationStorageDirectory
– Espacio de aplicación en almacenamiento externo.webtoappx.file.externalDataDirectory
– Dónde colocar archivos de datos específicos de la aplicación en un almacenamiento externo.webtoappx.file.externalCacheDirectory
– Caché de aplicaciones en almacenamiento externo.webtoappx.file.externalRootDirectory
– Raíz de almacenamiento externo (tarjeta SD).
Diseño del sistema de archivos
Ruta del dispositivo | webtoappx.file.* | AndroidExtraFileSystems | ¿r/w? | ¿persistente? | El sistema operativo se borra | privado |
---|---|---|---|---|---|---|
file:///android_asset/ | Directorio de aplicaciones | activos | r | N / A | N / A | Sí |
/data/data/<app-id>/ | directoriodealmacenamientodeaplicación | – | r/w | N / A | N / A | Sí |
cache | cachéDirectorio | cache | r/w | Sí | Sí* | Sí |
files | directorio de datos | archivos | r/w | Sí | No | Sí |
Documents | documentos | r/w | Sí | No | Sí | |
<sdcard>/ | directorioraízexterno | tarjeta SD | r/w*** | Sí | No | No |
Android/data/<app-id>/ | Directorio de almacenamiento de aplicaciones externas | – | r/w | Sí | No | No |
cache | directorio de caché externo | caché externo | r/w | Sí | No** | No |
files | directorio de datos externo | archivos externos | r/w | Sí | No | No |
Lista de códigos de error y significados
Cuando se produce un error, se utilizará uno de los siguientes códigos.
Código | Constante |
---|---|
1 | NOT_FOUND_ERR |
2 | SECURITY_ERR |
3 | ABORT_ERR |
4 | NOT_READABLE_ERR |
5 | ENCODING_ERR |
6 | NO_MODIFICATION_ALLOWED_ERR |
7 | INVALID_STATE_ERR |
8 | SYNTAX_ERR |
9 | INVALID_MODIFICATION_ERR |
10 | QUOTA_EXCEEDED_ERR |
11 | TYPE_MISMATCH_ERR |
12 | PATH_EXISTS_ERR |
Crear un archivo persistente
Antes de utilizar las API del complemento de archivos, puede obtener acceso al sistema de archivos mediante requestFileSystem
. Al hacer esto, puede solicitar almacenamiento persistente o temporal. El almacenamiento persistente no se eliminará a menos que el usuario otorgue permiso.
Cuando obtiene acceso al sistema de archivos mediante requestFileSystem
, el acceso se otorga solo para el sistema de archivos en el espacio aislado (el espacio aislado limita el acceso a la aplicación en sí), no para el acceso general a ninguna ubicación del sistema de archivos en el dispositivo. (Para acceder a ubicaciones del sistema de archivos fuera del almacenamiento en espacio aislado, utilice otros métodos como window.resolveLocalFileSystemURL, que admiten ubicaciones específicas de la plataforma. Para ver un ejemplo de esto, consulte Agregar un archivo).
Aquí hay una solicitud de almacenamiento persistente.
Ejemplo
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) { console.log('file system open: ' + fs.name); fs.root.getFile("newPersistentFile.txt", { create: true, exclusive: false }, function (fileEntry) { console.log("fileEntry is file?" + fileEntry.isFile.toString()); // fileEntry.name == 'someFile.txt' // fileEntry.fullPath == '/someFile.txt' writeFile(fileEntry, null); }, onErrorCreateFile); }, onErrorLoadFs);
La devolución de llamada exitosa recibe el objeto FileSystem (fs). Úselo fs.root
para devolver un objeto DirectoryEntry, que puede usar para crear u obtener un archivo (llamando a getFile
). En este ejemplo, fs.root
hay un objeto DirectoryEntry que representa el almacenamiento persistente en el sistema de archivos de espacio aislado.
La devolución de llamada exitosa getFile
recibe un objeto FileEntry. Puede utilizar esto para realizar operaciones de escritura y lectura de archivos.
Crear un archivo temporal
A continuación se muestra un ejemplo de una solicitud de almacenamiento temporal. El sistema operativo puede eliminar el almacenamiento temporal si el dispositivo se queda sin memoria.
Ejemplo
window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024, function (fs) { console.log('file system open: ' + fs.name); createFile(fs.root, "newTempFile.txt", false); }, onErrorLoadFs);
Cuando utiliza almacenamiento temporal, puede crear u obtener el archivo llamando a getFile
. Como en el ejemplo de almacenamiento persistente, esto le dará un objeto FileEntry que puede usar para operaciones de lectura o escritura.
Ejemplo
function createFile(dirEntry, fileName, isAppend) { // Creates a new file or returns the file if it already exists. dirEntry.getFile(fileName, {create: true, exclusive: false}, function(fileEntry) { writeFile(fileEntry, null, isAppend); }, onErrorCreateFile); }
Escribir en un archivo
Una vez que tenga un objeto FileEntry, puede escribir en el archivo llamando a createWriter
, que devuelve un objeto FileWriter en la devolución de llamada exitosa. Llame al método de escritura de FileWriter en write
el archivo.
Ejemplo
function writeFile(fileEntry, dataObj) { // Create a FileWriter object for our FileEntry (log.txt). fileEntry.createWriter(function (fileWriter) { fileWriter.onwriteend = function() { console.log("Successful file write..."); readFile(fileEntry); }; fileWriter.onerror = function (e) { console.log("Failed file write: " + e.toString()); }; // If data object is not passed in, // create a new Blob instead. if (!dataObj) { dataObj = new Blob(['some file data'], { type: 'text/plain' }); } fileWriter.write(dataObj); }); }
leer un archivo
También necesita un objeto FileEntry para leer un archivo existente. Utilice la propiedad de archivo de FileEntry para obtener la referencia del archivo y luego cree un nuevo objeto FileReader. Puede utilizar métodos como readAsText
iniciar la operación de lectura. Cuando se completa la operación de lectura, this.result
almacena el resultado de la operación de lectura.
Ejemplo
function readFile(fileEntry) { fileEntry.file(function (file) { var reader = new FileReader(); reader.onloadend = function () { console.log("Successful file read: " + this.result); displayFileData(fileEntry.fullPath + ": " + this.result); }; reader.readAsText(file); }, onErrorReadFile); }
Agregar un archivo usando métodos alternativos
Por supuesto, a menudo querrás agregar archivos existentes en lugar de crear otros nuevos. Aquí hay un ejemplo de eso. Este ejemplo muestra otra forma de acceder al sistema de archivos mediante window.resolveLocalFileSystemURL. En este ejemplo, pase la URL del archivo webtoapp multiplataforma, webtoappx.file.dataDirectory, a la función. La devolución de llamada exitosa recibe un objeto DirectoryEntry, que puede usar para hacer cosas como crear un archivo.
Ejemplo
window.resolveLocalFileSystemURL(webtoappx.file.dataDirectory, function (dirEntry) { console.log('file system open: ' + dirEntry.name); var isAppend = true; createFile(dirEntry, "fileToAppend.txt", isAppend); }, onErrorLoadFs);
Además de este uso, puede utilizarlo resolveLocalFileSystemURL
para obtener acceso a algunas ubicaciones del sistema de archivos que no forman parte del sistema de almacenamiento en espacio aislado. Consulte Dónde almacenar archivos para obtener más información; Muchas de estas ubicaciones de almacenamiento son específicas de la plataforma. También puede pasar ubicaciones del sistema de archivos multiplataforma para resolveLocalFileSystemURL
utilizar el protocolo cdvfile.
Para la operación de agregar, no hay nada nuevo en el createFile
uso del protocolo cdvfile. función que se llama en el código anterior (consulte los ejemplos anteriores para ver el código real). createFile
llamadas writeFile
. En writeFile
, verifica si se solicita una operación de adición.
Una vez que tenga un objeto FileWriter, llame al seek
método y pase el valor del índice para la posición donde desea escribir. En este ejemplo, también prueba si el archivo existe. Después de llamar a buscar, llame al método de escritura de FileWriter.
Ejemplo
function writeFile(fileEntry, dataObj, isAppend) { // Create a FileWriter object for our FileEntry (log.txt). fileEntry.createWriter(function (fileWriter) { fileWriter.onwriteend = function () { console.log("Successful file read..."); readFile(fileEntry); }; fileWriter.onerror = function (e) { console.log("Failed file read: " + e.toString()); }; // If we are appending data to file, go to the end of the file. if (isAppend) { try { fileWriter.seek(fileWriter.length); } catch (e) { console.log("file doesn't exist!"); } } fileWriter.write(dataObj); }); }
Almacenar un archivo binario existente
Ya mostramos cómo escribir en un archivo que acaba de crear en el sistema de archivos de espacio aislado. ¿Qué sucede si necesita obtener acceso a un archivo existente y convertirlo en algo que pueda almacenar en su dispositivo? En este ejemplo, obtiene un archivo mediante una solicitud xhr y luego lo guarda en la memoria caché del sistema de archivos de espacio aislado.
Antes de obtener el archivo, obtenga una referencia del sistema de archivos usando requestFileSystem
. Al pasar window.TEMPORARY en la llamada al método (igual que antes), el objeto FileSystem devuelto (fs) representa el caché en el sistema de archivos en espacio aislado. Úselo fs.root
para obtener el objeto DirectoryEntry que necesita.
Ejemplo
window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024, function (fs) { console.log('file system open: ' + fs.name); getSampleFile(fs.root); }, onErrorLoadFs);
Para completar, aquí está la solicitud xhr para obtener una imagen de Blob. No hay nada específico de webtoapp en este código, excepto que reenvía la referencia DirectoryEntry que ya obtuvo como argumento para la función saveFile. Guardará la imagen del blob y la mostrará más tarde después de leer el archivo (para validar la operación).
Ejemplo
function getSampleFile(dirEntry) { var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://webtoappx.com/src/img/webtoappx.png', true); xhr.responseType = 'blob'; xhr.onload = function () { if (this.status == 200) { var blob = new Blob([this.response], { type: 'image/png' }); saveFile(dirEntry, blob, "downloadedImage.png"); } }; xhr.send(); }
Después de obtener el archivo, copie el contenido a un archivo nuevo. El objeto DirectoryEntry actual ya está asociado con la caché de la aplicación.
function saveFile(dirEntry, fileData, fileName) { dirEntry.getFile(fileName, { create: true, exclusive: false }, function (fileEntry) { writeFile(fileEntry, fileData); }, onErrorCreateFile); }
En writeFile, pasa el objeto Blob como dataObj y lo guardará en el nuevo archivo.
function writeFile(fileEntry, dataObj, isAppend) { // Create a FileWriter object for our FileEntry (log.txt). fileEntry.createWriter(function (fileWriter) { fileWriter.onwriteend = function () { console.log("Successful file write..."); if (dataObj.type == "image/png") { readBinaryFile(fileEntry); } else { readFile(fileEntry); } }; fileWriter.onerror = function (e) { console.log("Failed file write: " + e.toString()); }; fileWriter.write(dataObj); }); }
Después de escribir en el archivo, léalo y muéstrelo. Guardaste la imagen como datos binarios, por lo que puedes leerla usando FileReader.readAsArrayBuffer.
function readBinaryFile(fileEntry) { fileEntry.file(function (file) { var reader = new FileReader(); reader.onloadend = function () { console.log("Successful file write: " + this.result); displayFileData(fileEntry.fullPath + ": " + this.result); var blob = new Blob([new Uint8Array(this.result)], { type: "image/png" }); displayImage(blob); }; reader.readAsArrayBuffer(file); }, onErrorReadFile); }
Después de leer los datos, puede mostrar la imagen usando un código como este. Utilice window.URL.createObjectURL para obtener una cadena DOM para la imagen de Blob.
function displayImage(blob) { // Displays image if result is a valid DOM string for an image. var elem = document.getElementById('imageFile'); // Note: Use window.URL.revokeObjectURL when finished with image. elem.src = window.URL.createObjectURL(blob); }
Display an image file
Para mostrar una imagen usando FileEntry, puede llamar al toURL
método.
function displayImageByFileURL(fileEntry) { var elem = document.getElementById('imageFile'); elem.src = fileEntry.toURL(); }
Si está utilizando algunos URI específicos de la plataforma en lugar de FileEntry y desea mostrar una imagen, es posible que deba incluir la parte principal del URI en el elemento Content-Security-Policy en index.html.
Crear directorios
En el código aquí, crea directorios en la raíz de la ubicación de almacenamiento de la aplicación. Puede utilizar este código con cualquier ubicación de almacenamiento grabable (es decir, cualquier DirectoryEntry). Aquí, escribe en el caché de la aplicación (suponiendo que usó window.TEMPORARY para obtener su objeto FileSystem) pasando fs.root a esta función.
Este código crea la carpeta /NewDirInRoot/images en el caché de la aplicación. Para conocer los valores específicos de la plataforma, consulte Diseños del sistema de archivos.
function createDirectory(rootDirEntry) { rootDirEntry.getDirectory('NewDirInRoot', { create: true }, function (dirEntry) { dirEntry.getDirectory('images', { create: true }, function (subDirEntry) { createFile(subDirEntry, "fileInNewSubDir.txt"); }, onErrorGetDir); }, onErrorGetDir); }
Al crear subcarpetas, debe crear cada carpeta por separado como se muestra en el código anterior.