Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
por Tom FitzMacken
En este artículo se explica cómo leer, escribir, anexar, eliminar y cargar archivos en un sitio de ASP.NET Web Pages (Razor).
Nota:
Si desea cargar imágenes y manipularlas (por ejemplo, voltearlas o cambiarlas de tamaño), vea Trabajar con imágenes en un sitio de páginas web de ASP.NET.
Lo que aprenderá:
- Cómo crear un archivo de texto y escribir datos en él.
- Cómo anexar datos a un archivo existente.
- Cómo leer un archivo y mostrarlo desde él.
- Cómo eliminar archivos de un sitio web.
- Cómo permitir que los usuarios carguen un archivo o varios archivos.
Estas son las ASP.NET características de programación introducidas en el artículo:
- Objeto
File, que proporciona una manera de administrar archivos.- El asistente
FileUpload.- Objeto
Path, que proporciona métodos que permiten manipular nombres de archivo y ruta de acceso.Versiones de software usadas en el tutorial
- páginas web de ASP.NET (Razor) 2
- WebMatrix 2
Este tutorial también funciona con WebMatrix 3.
Crear un archivo de texto y escribir datos en él
Además de usar una base de datos en su sitio web, puede trabajar con archivos. Por ejemplo, puede usar archivos de texto como una manera sencilla de almacenar datos para el sitio. (Un archivo de texto que se usa para almacenar datos a veces se denomina archivo plano). Los archivos de texto pueden tener diferentes formatos, como .txt, .xmlo .csv (valores delimitados por comas).
Si desea almacenar datos en un archivo de texto, puede usar el File.WriteAllText método para especificar el archivo que se va a crear y los datos que se van a escribir en él. En este procedimiento, creará una página que contiene un formulario simple con tres input elementos (nombre, apellidos y dirección de correo electrónico) y un botón Enviar . Cuando el usuario envíe el formulario, almacenará la entrada del usuario en un archivo de texto.
Cree una carpeta denominada App_Data, si aún no existe.
En la raíz de su sitio web, cree un archivo denominado UserData.cshtml.
Reemplace el contenido existente por lo siguiente:
@{ var result = ""; if (IsPost) { var firstName = Request["FirstName"]; var lastName = Request["LastName"]; var email = Request["Email"]; var userData = firstName + "," + lastName + "," + email + Environment.NewLine; var dataFile = Server.MapPath("~/App_Data/data.txt"); File.WriteAllText(@dataFile, userData); result = "Information saved."; } } <!DOCTYPE html> <html> <head> <title>Write Data to a File</title> </head> <body> <form id="form1" method="post"> <div> <table> <tr> <td>First Name:</td> <td><input id="FirstName" name="FirstName" type="text" /></td> </tr> <tr> <td>Last Name:</td> <td><input id="LastName" name="LastName" type="text" /></td> </tr> <tr> <td>Email:</td> <td><input id="Email" name="Email" type="text" /></td> </tr> <tr> <td></td> <td><input type="submit" value="Submit"/></td> </tr> </table> </div> <div> @if(result != ""){ <p>Result: @result</p> } </div> </form> </body> </html>El marcado HTML crea el formulario con los tres cuadros de texto. En el código, se usa la
IsPostpropiedad para determinar si la página se ha enviado antes de empezar a procesarla.La primera tarea consiste en obtener la entrada del usuario y asignarla a variables. A continuación, el código concatena los valores de las variables independientes en una cadena delimitada por comas, que luego se almacena en una variable diferente. Observe que el separador de comas es una cadena contenida entre comillas (","), porque literalmente va a insertar una coma en la cadena grande que está creando. Al final de los datos que concatene, agregue
Environment.NewLine. Esto agrega un salto de línea (un carácter de nueva línea). Lo que va a crear con toda esta concatenación es una cadena similar a la siguiente:David,Jones,davidj@contoso.com(Con un salto de línea invisible al final).
A continuación, cree una variable (
dataFile) que contenga la ubicación y el nombre del archivo en el que almacenar los datos. La configuración de la ubicación requiere un control especial. En los sitios web, es una práctica incorrecta hacer referencia en el código a rutas de acceso absolutas, como C:\Folder\File.txt para archivos en el servidor web. Si se mueve un sitio web, una ruta absoluta será incorrecto. Además, para un sitio hospedado (en lugar de en tu propio equipo), usualmente no sabes cuál es la ruta correcta al escribir el código.Pero a veces (como ahora, para escribir un archivo), necesita una ruta de acceso completa. La solución consiste en usar el
MapPathmétodo delServerobjeto . Esto devuelve la ruta de acceso completa a su sitio web. Para obtener la ruta de acceso de la raíz del sitio web, use el operador~(para representar la raíz virtual del sitio) enMapPath. (También puede pasarle un nombre de subcarpeta, como ~/App_Data/, para obtener la ruta de acceso de esa subcarpeta). A continuación, puede concatenar información adicional sobre cualquier valor devuelto por el método para crear una ruta de acceso completa. En este ejemplo, agregará un nombre de archivo. (Puede obtener más información sobre cómo trabajar con rutas de acceso de archivos y carpetas en Introducción a ASP.NET programación de páginas web mediante la sintaxis de Razor).El archivo se guarda en la carpeta App_Data . Esta carpeta es una carpeta especial en ASP.NET que se usa para almacenar archivos de datos, como se describe en Introducción al trabajo con una base de datos en ASP.NET sitios de páginas web.
El
WriteAllTextmétodo delFileobjeto escribe los datos en el archivo. Este método toma dos parámetros: el nombre (con ruta de acceso) del archivo en el que se va a escribir y los datos reales que se van a escribir. Observe que el nombre del primer parámetro tiene un@carácter como prefijo. Esto le indica a ASP.NET que estás proporcionando un literal de cadena y que los caracteres como "/" no deben interpretarse de maneras especiales. (Para obtener más información, vea Introducción a ASP.NET programación web mediante la sintaxis de Razor).Nota:
Para que el código guarde archivos en la carpeta App_Data , la aplicación necesita permisos de lectura y escritura para esa carpeta. En el equipo de desarrollo, esto no suele presentar un problema. Sin embargo, al publicar el sitio en el servidor web de un proveedor de hospedaje, es posible que tenga que establecer explícitamente esos permisos. Si ejecuta este código en el servidor de un proveedor de hospedaje y recibe errores, consulte con el proveedor de hospedaje para averiguar cómo establecer esos permisos.
Ejecute la página en un explorador.
Escriba los valores en los campos y, a continuación, haga clic en Enviar.
Cierre el explorador.
Regrese al proyecto y refresque la vista.
Abra el archivo data.txt . Los datos que envió en el formulario están en el archivo.
Cierre el archivo data.txt .
Anexar datos a un archivo existente
En el ejemplo anterior, usó WriteAllText para crear un archivo de texto que tiene solo un fragmento de datos en él. Si llama al método de nuevo y le pasa el mismo nombre de archivo, el archivo existente se sobrescribe completamente. Sin embargo, después de crear un archivo, a menudo desea agregar nuevos datos al final del archivo. Puede hacerlo mediante el AppendAllText método del File objeto .
En el sitio web, realice una copia del archivo UserData.cshtml y asigne el nombre UserDataMultiple.cshtml.
Reemplace el bloque de código antes de la etiqueta de apertura
<!DOCTYPE html>por el siguiente bloque de código:@{ var result = ""; if (IsPost) { var firstName = Request["FirstName"]; var lastName = Request["LastName"]; var email = Request["Email"]; var userData = firstName + "," + lastName + "," + email + Environment.NewLine; var dataFile = Server.MapPath("~/App_Data/data.txt"); File.AppendAllText (@dataFile, userData); result = "Information saved."; } }Este código tiene un cambio en él del ejemplo anterior. En lugar de usar
WriteAllText, usa elthe AppendAllTextmétodo . Los métodos son similares, excepto queAppendAllTextagrega los datos al final del archivo. Al igual que conWriteAllText,AppendAllTextcrea el archivo si aún no existe.Ejecute la página en un explorador.
Escriba los valores de los campos y, a continuación, haga clic en Enviar.
Agregue más datos y vuelva a enviar el formulario.
Vuelva al proyecto, haga clic con el botón derecho en la carpeta del proyecto y, a continuación, haga clic en Actualizar.
Abra el archivo data.txt . Ahora contiene los nuevos datos que acaba de escribir.
Leer y mostrar datos de un archivo
Incluso si no necesita escribir datos en un archivo de texto, es probable que a veces necesite leer datos de uno. Para ello, puede volver a usar el File objeto . Puede usar el File objeto para leer cada línea individualmente (separada por saltos de línea) o para leer un elemento individual independientemente de cómo estén separados.
Este procedimiento muestra cómo leer y mostrar los datos que creó en el ejemplo anterior.
En la raíz de su sitio web, cree un archivo denominado DisplayData.cshtml.
Reemplace el contenido existente por lo siguiente:
@{ var result = ""; Array userData = null; char[] delimiterChar = {','}; var dataFile = Server.MapPath("~/App_Data/data.txt"); if (File.Exists(dataFile)) { userData = File.ReadAllLines(dataFile); if (userData == null) { // Empty file. result = "The file is empty."; } } else { // File does not exist. result = "The file does not exist."; } } <!DOCTYPE html> <html> <head> <title>Reading Data from a File</title> </head> <body> <div> <h1>Reading Data from a File</h1> @result @if (result == "") { <ol> @foreach (string dataLine in userData) { <li> User <ul> @foreach (string dataItem in dataLine.Split(delimiterChar)) { <li>@dataItem</li > } </ul> </li> } </ol> } </div> </body> </html>El código comienza leyendo el archivo que creó en el ejemplo anterior en una variable denominada
userData, con esta llamada al método :File.ReadAllLines(dataFile)El código para hacerlo está dentro de una
ifinstrucción . Cuando quiera leer un archivo, es recomendable usar elFile.Existsmétodo para determinar primero si el archivo está disponible. El código también comprueba si el archivo está vacío.El cuerpo de la página contiene dos
foreachbucles, uno anidado dentro del otro. El bucle externoforeachobtiene una línea a la vez del archivo de datos. En este caso, las líneas se definen mediante saltos de línea en el archivo, es decir, cada elemento de datos está en su propia línea. El bucle externo crea un nuevo elemento (<li>elemento) dentro de una lista ordenada (<ol>elemento).El bucle interno divide cada línea de datos en elementos (campos) mediante una coma como delimitador. (En función del ejemplo anterior, esto significa que cada línea contiene tres campos: el nombre, el apellido y la dirección de correo electrónico, cada uno separado por una coma). El bucle interno también crea una
<ul>lista y muestra un elemento de lista para cada campo de la línea de datos.El código muestra cómo usar dos tipos de datos, una matriz y el tipo de
chardatos. La matriz es necesaria porque elFile.ReadAllLinesmétodo devuelve datos como una matriz. Elchartipo de datos es necesario porque elSplitmétodo devuelve unarrayen el que cada elemento es del tipochar. (Para obtener información sobre las matrices, vea Introducción a ASP.NET programación web mediante la sintaxis de Razor).Ejecute la página en un explorador. Se muestran los datos especificados para los ejemplos anteriores.
Sugerencia
Mostrar datos de un archivo delimitado por comas de Microsoft Excel
Puede usar Microsoft Excel para guardar los datos contenidos en una hoja de cálculo como un archivo delimitado por comas (.csv archivo). Cuando lo hace, el archivo se guarda en texto sin formato, no en formato de Excel. Cada fila de la hoja de cálculo está separada por un salto de línea en el archivo de texto y cada elemento de datos está separado por una coma. Puede usar el código que se muestra en el ejemplo anterior para leer un archivo delimitado por comas de Excel simplemente cambiando el nombre del archivo de datos en el código.
Eliminar archivos
Para eliminar archivos de su sitio web, puede usar el File.Delete método . Este procedimiento muestra cómo permitir que los usuarios eliminen una imagen (.jpg archivo) de una carpeta images si conocen el nombre del archivo.
Nota:
Importante En un sitio web de producción, normalmente restringe quién puede realizar cambios en los datos. Para obtener información sobre cómo configurar la pertenencia y sobre las formas de autorizar a los usuarios a realizar tareas en el sitio, vea Agregar seguridad y pertenencia a un sitio de páginas web de ASP.NET.
En el sitio web, cree una subcarpeta denominada images.
Copie uno o varios archivos .jpg en la carpeta images .
En la raíz del sitio web, cree un nuevo archivo denominado FileDelete.cshtml.
Reemplace el contenido existente por lo siguiente:
@{ bool deleteSuccess = false; var photoName = ""; if (IsPost) { photoName = Request["photoFileName"] + ".jpg"; var fullPath = Server.MapPath("~/images/" + photoName); if (File.Exists(fullPath)) { File.Delete(fullPath); deleteSuccess = true; } } } <!DOCTYPE html> <html> <head> <title>Delete a Photo</title> </head> <body> <h1>Delete a Photo from the Site</h1> <form name="deletePhoto" action="" method="post"> <p>File name of image to delete (without .jpg extension): <input name="photoFileName" type="text" value="" /> </p> <p><input type="submit" value="Submit" /></p> </form> @if(deleteSuccess) { <p> @photoName deleted! </p> } </body> </html>Esta página contiene un formulario donde los usuarios pueden escribir el nombre de un archivo de imagen. No es necesario que introduzcan la extensión del nombre de archivo .jpg; al restringir de esta manera el nombre de archivo, ayudas a evitar que los usuarios eliminen archivos arbitrarios en tu sitio.
El código lee el nombre de archivo que el usuario ha escrito y, a continuación, construye una ruta de acceso completa. Para crear la ruta de acceso, el código usa la ruta de acceso del sitio web actual (como devuelve el
Server.MapPathmétodo ), el nombre de la carpeta images , el nombre que el usuario ha proporcionado y ".jpg" como una cadena literal.Para eliminar el archivo, el código llama al
File.Deletemétodo y le pasa la ruta de acceso completa que acaba de construir. Al final del marcado, el código muestra un mensaje de confirmación de que se eliminó el archivo.Ejecute la página en un explorador.
Escriba el nombre del archivo que se va a eliminar y, a continuación, haga clic en Enviar. Si se eliminó el archivo, el nombre del archivo se muestra en la parte inferior de la página.
Permitir que los usuarios carguen un archivo
El FileUpload asistente permite a los usuarios cargar archivos en su sitio web. En el procedimiento siguiente se muestra cómo permitir que los usuarios carguen un único archivo.
Agregue la biblioteca de asistentes web de ASP.NET al sitio web, tal como se describe en Instalación de asistentes en un sitio de páginas web de ASP.NET, si no lo agréguelo anteriormente.
En la carpeta App_Data , cree una carpeta y asígne un nombre UploadedFiles.
En la raíz, cree un nuevo archivo denominado FileUpload.cshtml.
Reemplace el contenido existente de la página por lo siguiente:
@using Microsoft.Web.Helpers; @{ var fileName = ""; if (IsPost) { var fileSavePath = ""; var uploadedFile = Request.Files[0]; fileName = Path.GetFileName(uploadedFile.FileName); fileSavePath = Server.MapPath("~/App_Data/UploadedFiles/" + fileName); uploadedFile.SaveAs(fileSavePath); } } <!DOCTYPE html> <html> <head> <title>FileUpload - Single-File Example</title> </head> <body> <h1>FileUpload - Single-File Example</h1> @FileUpload.GetHtml( initialNumberOfFiles:1, allowMoreFilesToBeAdded:false, includeFormTag:true, uploadText:"Upload") @if (IsPost) { <span>File uploaded!</span><br/> } </body> </html>La sección principal de la página usa el
FileUploadasistente para crear el cuadro de carga y los botones que probablemente te resulten familiares.
Las propiedades que establezca para el
FileUploadasistente especifican que desea que un único cuadro para que el archivo se cargue y que desee que el botón enviar lea Cargar. (Agregará más cuadros más adelante en el artículo).Cuando el usuario hace clic en Cargar, el código de la parte superior de la página obtiene el archivo y lo guarda. El
Requestobjeto que se usa normalmente para obtener valores de los campos de formulario también tiene unaFilesmatriz que contiene el archivo (o archivos) que se han cargado. Puede obtener archivos individuales de posiciones específicas en la matriz( por ejemplo, para obtener el primer archivo cargado, obtenerRequest.Files[0], para obtener el segundo archivo, obtenerRequest.Files[1], y así sucesivamente. (Recuerde que en la programación, el recuento suele comenzar en cero).Cuando captura un archivo cargado, lo coloca en una variable (aquí,
uploadedFile) para que pueda manipularlo. Para determinar el nombre del archivo cargado, solo tiene que obtener suFileNamepropiedad. Sin embargo, cuando el usuario carga un archivo,FileNamecontiene el nombre original del usuario, que incluye toda la ruta de acceso. Podría tener este aspecto:C:\Users\Public\Sample.txt
Pero no quiere toda esa información del camino, ya que esa es la ruta en el equipo del usuario, no para el servidor. Solo quiere el nombre de archivo real (Sample.txt). Puede extraer solo el archivo de una ruta de acceso utilizando el método
Path.GetFileName, de la siguiente manera:Path.GetFileName(uploadedFile.FileName)El
Pathobjeto es una utilidad que tiene una serie de métodos como este que se pueden usar para quitar rutas, combinar rutas, etc.Una vez que haya obtenido el nombre del archivo cargado, puede crear una nueva ruta de acceso para dónde desea almacenar el archivo cargado en su sitio web. En este caso, combinará
Server.MapPath, los nombres de carpeta (App_Data/UploadedFiles) y el nombre de archivo recién quitado para crear una nueva ruta de acceso. A continuación, puede llamar al método del archivo cargadoSaveAspara guardar efectivamente el archivo.Ejecute la página en un explorador.
Haga clic en Examinar y, a continuación, seleccione un archivo para cargarlo.
El cuadro de texto situado junto al botón Examinar contendrá la ruta de acceso y la ubicación del archivo.
Haga clic en Cargar.
En el sitio web, haga clic con el botón derecho en la carpeta del proyecto y, a continuación, haga clic en Actualizar.
Abra la carpeta UploadedFiles . El archivo que cargó se encuentra en la carpeta .
Permitir que los usuarios carguen varios archivos
En el ejemplo anterior, permite que los usuarios carguen un archivo. Pero puede usar el FileUpload asistente para cargar más de un archivo a la vez. Esto resulta útil para escenarios como cargar fotos, donde cargar un archivo a la vez es tedioso. (Puede leer sobre cómo cargar fotos en Trabajar con imágenes en un sitio de páginas web de ASP.NET). En este ejemplo se muestra cómo permitir que los usuarios carguen dos a la vez, aunque puede usar la misma técnica para cargar más de eso.
Agregue la biblioteca de asistentes web de ASP.NET al sitio web, tal como se describe en Instalación de asistentes en un sitio de páginas web de ASP.NET, si aún no lo ha hecho.
Cree una página denominada FileUploadMultiple.cshtml.
Reemplace el contenido existente de la página por lo siguiente:
@using Microsoft.Web.Helpers; @{ var message = ""; if (IsPost) { var fileName = ""; var fileSavePath = ""; int numFiles = Request.Files.Count; int uploadedCount = 0; for(int i =0; i < numFiles; i++) { var uploadedFile = Request.Files[i]; if (uploadedFile.ContentLength > 0) { fileName = Path.GetFileName(uploadedFile.FileName); fileSavePath = Server.MapPath("~/App_Data/UploadedFiles/" + fileName); uploadedFile.SaveAs(fileSavePath); uploadedCount++; } } message = "File upload complete. Total files uploaded: " + uploadedCount.ToString(); } } <!DOCTYPE html> <html> <head><title>FileUpload - Multiple File Example</title></head> <body> <form id="myForm" method="post" enctype="multipart/form-data" action=""> <div> <h1>File Upload - Multiple-File Example</h1> @if (!IsPost) { @FileUpload.GetHtml( initialNumberOfFiles:2, allowMoreFilesToBeAdded:true, includeFormTag:true, addText:"Add another file", uploadText:"Upload") } <span>@message</span> </div> </form> </body> </html>En este ejemplo, el
FileUploadasistente en el cuerpo de la página está configurado para permitir que los usuarios carguen dos archivos de forma predeterminada. Dado queallowMoreFilesToBeAddedse establece entrue, el auxiliar representa un vínculo que permite al usuario agregar más cajas de subida.
Para procesar los archivos que carga el usuario, el código usa la misma técnica básica que usó en el ejemplo anterior: obtenga un archivo de
Request.Filesy guárdelo. (Incluye los distintos pasos que debe seguir para obtener el nombre de archivo y la ruta de acceso correctos). La innovación esta vez es que el usuario podría cargar varios archivos y no sabe cuántos. Para averiguarlo, puede obtenerRequest.Files.Count.Con este número a mano, puede recorrer
Request.Files, capturar cada archivo a su vez y guardarlo. Cuando desee recorrer un número conocido de veces a través de una colección, puede usar unforbucle, de la siguiente manera:for(int i =0; i < numFiles; i++) { var uploadedFile = Request.Files[i]; if (uploadedFile.ContentLength > 0) { fileName = Path.GetFileName(uploadedFile.FileName); // etc. }La variable
ies solo un contador temporal que pasará de cero a cualquier límite superior que establezca. En este caso, el límite superior es el número de archivos. Pero dado que el contador se inicia en cero, como es habitual para los escenarios de recuento en ASP.NET, el límite superior es realmente uno menor que el recuento de archivos. (Si se cargan tres archivos, el recuento es cero a 2).La
uploadedCountvariable totaliza todos los archivos que se cargan y guardan correctamente. Este código tiene en cuenta la posibilidad de que un archivo esperado no pueda cargarse.Ejecute la página en un explorador. El explorador muestra la página y sus dos cuadros de carga.
Seleccione dos archivos para cargar.
Haga clic en Agregar otro archivo. La página muestra una caja de carga nueva.
Haga clic en Cargar.
En el sitio web, haga clic con el botón derecho en la carpeta del proyecto y, a continuación, haga clic en Actualizar.
Abra la carpeta UploadedFiles para ver los archivos cargados correctamente.