Inicio rápido: enviar un archivo a un dispositivo de almacenamiento (HTML)
[ Este artículo está destinado a desarrolladores de Windows 8.x y Windows Phone 8.x que escriben aplicaciones de Windows en tiempo de ejecución. Si estás desarrollando para Windows 10, consulta la documentación más reciente
Este tutorial te muestra cómo copiar un archivo en un dispositivo de almacenamiento extraíble creando una instancia de un objeto de almacenamiento mediante Windows.Devices.Portable.Storage.FromId.
Objetivo: Te enseñaremos a usar la API de Windows.Devices.Enumeration para enumerar dispositivos de almacenamiento extraíbles y elegir uno de ellos para crear una instancia de un objeto de almacenamiento, que después se puede usar como destino de una operación de copyAsync.
Requisitos previos
Debes tener conocimientos de JavaScript y HTML.
Debes tener disponible un dispositivo de almacenamiento extraíble.
Tiempo para finalizar: 20 minutos.
Instrucciones
1. Abrir Microsoft Visual Studio
Abre una sesión de Visual Studio.
2. Crear un nuevo proyecto
En el cuadro de diálogo Nuevo proyecto, elige una aplicación vacía en los tipos de proyecto JavaScript.
3. Declarar la funcionalidad de almacenamiento extraíble
Haz doble clic en package.appxmanifest en el Explorador de soluciones. Selecciona la pestaña Funcionalidad. Activa la opción Almacenamiento extraíble en la lista Funcionalidad.
4. Insertar el código JavaScript y HTML de la aplicación
Abre el archivo Default.html y copia el código HTML siguiente, sustituyendo su contenido original.
<!DOCTYPE html>
<html>
<head>
<title>Removable Storage Devices</title>
<link rel="stylesheet" href="/winjs/css/ui-dark.css" />
<script type = "text/javascript" >
Enum = Windows.Devices.Enumeration;
// Enumerate removable storage devices.
// The success callback selects the removable storage to use.
function pickStorage(){
Enum.DeviceInformation.findAllAsync(
Windows.Devices.Portable.StorageDevice.getDeviceSelector(),
null).then(
successCallback,
errorCallback);
}
// Handler that's called when removable storages are found.
// The storageDevices parameter is of type
// Windows.Devices.Enumeration.DeviceInformationCollection
function successCallback(storageDevices){
var removableStorage;
if (storageDevices.length) {
try {
// Create an IStorageItem from the first removable storage device
removableStorage = Windows.Devices.Portable.StorageDevice.fromId(
storageDevices.getAt(0).id);
} catch (e) {
document.getElementById("output").innerHTML =
"Error creating storage item: " + e.message;
}
if (removableStorage != null) {
PickAndSend(removableStorage, removableStorage.name);
}
}
}
function errorCallback(e) {
document.getElementById("output").innerHTML = "Error: " + e.message;
}
// Pick a file, and send it to the removable storage device
// removableStorage: The IStorageItem representing the storage device
// removableStorageName: The name of the storage device
function PickAndSend(removableStorage, removableStorageName) {
// Create the picker for selecting an image file
var picker = new Windows.Storage.Pickers.FileOpenPicker();
// Set the collection of types that the file open picker displays.
picker.fileTypeFilter.replaceAll([".jpg", ".png", ".gif"]);
// Set the initial location where the file picker looks
picker.suggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
picker.pickSingleFileAsync().then(
function (sourceFile) {
// sourceFile is null if the user
// clicked cancel from the picker
if (sourceFile == null) {
document.getElementById("output").innerHTML =
"No file was picked.";
}
else {
// Copy the file to the storage device
// using StorageFile.copyAsync
sourceFile.copyAsync(removableStorage).then(
function (newFile) {
document.getElementById("output").innerHTML =
"Created file: " + newFile.name + " on " +
removableStorageName + "<br/>";
},
function (e) {
// A failure here could mean that the removable storage
// does not allow file creation on its root.
// We try to find a folder to copy the file to.
copyToFirstAvailableFolder(
removableStorage, sourceFile);
}); // end sourceFile.copyAsync
} // end if (sourceFile)
}); // end pickSingleFileAsync.then
}
function copyToFirstAvailableFolder(removableStorage, sourceFile) {
// Construct a recursive folder search
var queryOptions = new Windows.Storage.Search.QueryOptions(
Windows.Storage.Search.CommonFolderQuery.defaultQuery);
queryOptions.folderDepth = Windows.Storage.Search.FolderDepth.deep;
var deepFolderQuery =
removableStorage.createFolderQueryWithOptions(queryOptions);
deepFolderQuery.getFoldersAsync().then(
function (folders) {
copyToFolder(folders, 0, sourceFile);
},
function (e) {
document.getElementById("output").innerHTML =
"Failed to find any folders to copy to: " + e.message;
});
}
function copyToFolder(folderList, currentIndex, sourceFile) {
if (currentIndex === folderList.length) {
document.getElementById("output").innerHTML =
"Failed to find a writable folder to copy to";
return;
}
var destinationFolder = folderList[currentIndex];
document.getElementById("output").innerHTML =
"Trying folder: " + destinationFolder.name + "...";
performCopyToDevice(
destinationFolder,
sourceFile,
function (newFile) {
document.getElementById("output").innerHTML += "Created file: " +
newFile.name + " in folder: " + destinationFolder.name + "<br/>";
},
function (e) {
copyToFolder(folderList, currentIndex + 1, sourceFile);
});
}
function performCopyToDevice(
destinationFolder, sourceFile, completedHandler, errorHandler) {
if (itemInFileSystemStorage(destinationFolder)) {
sourceFile.copyAsync(destinationFolder).then(
completedHandler, errorHandler);
} else {
// Use createFile/stream copy for non-file-system-based storages
var destOutputStream = null;
var newFile = null;
return destinationFolder.createFileAsync(sourceFile.fileName).
then(
function (file) {
newFile = file;
return newFile.openAsync(
Windows.Storage.FileAccessMode.readWrite);
},
errorHandler).
then(
function (destStream) {
destOutputStream = destStream.getOutputStreamAt(0);
return sourceFile.openForReadAsync();
},
errorHandler).
then(
function (sourceInputStream) {
Windows.Storage.Streams.RandomAccessStream.copy(
sourceInputStream, destOutputStream);
return destOutputStream.flushAsync();
},
errorHandler).
then(
function () {
completedHandler(newFile);
},
errorHandler);
}
}
function itemInFileSystemStorage(item) {
// Items in file-system-backed storages have a non-zero-length path
return (item.path.length > 0);
}
</script>
</head>
<body>
<p>
Click "Send File" <br /> </p>
<input type="button" onclick="pickStorage()"
value="Pick and Send File to Storage" /><br />
<div id=output></div>
</body>
</html>
5. Probar la aplicación
- Conecta el dispositivo de almacenamiento extraíble, si aún no está conectado.
- En el menú Depurar, haz clic en Iniciar depuración para probar la solución.
- Haz clic en el botón Pick and Send File to Storage (Elegir y enviar archivo a almacenamiento) para elegir un archivo mediante el Selector de archivos y copiarlo en el dispositivo de almacenamiento.
Nota Si obtienes un error, realiza las siguientes comprobaciones:
- Asegúrate de que has habilitado el acceso al almacenamiento extraíble. Para ello, abre package.appxmanifest en el Explorador de soluciones y activa Almacenamiento extraíble en la pestaña Funcionalidades.
Resumen
Has aprendido a copiar archivos locales en dispositivos de almacenamiento extraíbles. En el próximo tutorial te enseñaremos a obtener un archivo de imagen desde un dispositivo de almacenamiento extraíble y a mostrarlo.