Home Android Ficheros en Android (I): Memoria Interna

Ficheros en Android (I): Memoria Interna

by sgoliver

En artículos anteriores del Curso de Programación Android hemos visto ya diversos métodos para almacenar datos en nuestras aplicaciones, como por ejemplo los ficheros de preferencias compartidas o las bases de datos SQLite. Estos mecanismos son perfectos para almacenar datos estructurados, pero en ocasiones nos seguirá siendo útil poder disponer también de otros ficheros auxiliares de datos, probáblemente con otro tipo de contenidos y formatos. Por ello, en Android también podremos manipular ficheros tradicionales de una forma muy similar a como se realiza en Java.

Lo primero que hay que tener en cuenta es dónde queremos almacenar los ficheros y el tipo de acceso que queremos tener a ellos. Así, podremos leer y escribir ficheros localizados en:

  1. La memoria interna del dispositivo.
  2. La tarjeta SD externa, si existe.
  3. La propia aplicación, en forma de recurso.

En los dos próximos artículos aprenderemos a manipular ficheros almacenados en cualquiera de estos lugares, comentando las particularidades de cada caso.

Veamos en primer lugar cómo trabajar con la memoria interna del dispositivo. Cuando almacenamos ficheros en la memoria interna debemos tener en cuenta las limitaciones de espacio que tienen muchos dispositivos, por lo que no deberíamos abusar de este espacio utilizando ficheros de gran tamaño.

Escribir ficheros en la memoria interna es muy sencillo. Android proporciona para ello el método openFileOutput(), que recibe como parámetros el nombre del fichero y el modo de acceso con el que queremos abrir el fichero. Este modo de acceso puede variar entre MODE_PRIVATE para acceso privado desde nuestra aplicación (crea el fichero o lo sobrescribe si ya existe), MODE_APPEND para añadir datos a un fichero ya existente, MODE_WORLD_READABLE para permitir a otras aplicaciones leer el fichero, o MODE_WORLD_WRITABLE para permitir a otras aplicaciones escribir sobre el fichero. Los dos últimos no deberían utilizarse dada su peligrosidad, de hecho, han sido declarados como obsoletos (deprecated) en la API 17.

Este método devuelve una referencia al stream de salida asociado al fichero (en forma de objeto FileOutputStream), a partir del cual ya podremos utilizar los métodos de manipulación de ficheros tradicionales del lenguaje java (api java.io). Como ejemplo, convertiremos este stream a un OutputStreamWriter para escribir una cadena de texto al fichero.

try
{
	OutputStreamWriter fout=
		new OutputStreamWriter(
			openFileOutput("prueba_int.txt", Context.MODE_PRIVATE));

	fout.write("Texto de prueba.");
	fout.close();
}
catch (Exception ex)
{
	Log.e("Ficheros", "Error al escribir fichero a memoria interna");
}

Está bien, ya hemos creado un fichero de texto en la memoria interna, ¿pero dónde exactamente? Tal como ocurría con las bases de datos SQLite, Android almacena por defecto los ficheros creados en una ruta determinada, que en este caso seguirá el siguiente patrón:

/data/data/paquete.java/files/nombre_fichero

En mi caso particular, la ruta será

/data/data/net.sgoliver.android.ficheros/files/prueba_int.txt

Si ejecutamos el código anterior podremos comprobar en el DDMS cómo el fichero se crea correctamente en la ruta indicada (Al final del artículo hay un enlace a una aplicación de ejemplo sencilla donde incluyo un botón por cada uno de los puntos que vamos a comentar en el artículo).

ddms_fileexplorer_ficheros

Por otra parte, leer ficheros desde la memoria interna es igual de sencillo, y procederemos de forma análoga, con la única diferencia de que utilizaremos el método openFileInput() para abrir el fichero, y los métodos de lectura de java.io para leer el contenido.

try
{
	BufferedReader fin =
		new BufferedReader(
			new InputStreamReader(
				openFileInput("prueba_int.txt")));

	String texto = fin.readLine();
	fin.close();
}
catch (Exception ex)
{
	Log.e("Ficheros", "Error al leer fichero desde memoria interna");
}

La segunda forma de almacenar ficheros en la memoria interna del dispositivo es incluirlos como recurso en la propia aplicación. Aunque este método es útil en muchos casos, sólo debemos utilizarlo cuando no necesitemos realizar modificaciones sobre los ficheros, ya que tendremos limitado el acceso a sólo lectura.

Para incluir un fichero como recurso de la aplicación debemos colocarlo en la carpeta «/res/raw» de nuestro proyecto de Eclipse. Esta carpeta no suele estar creada por defecto, por lo que deberemos crearla manualmente en Eclipse desde el menú contextual con la opción «New / Folder«.

crear-carpeta-raw

Una vez creada la carpeta /raw podremos colocar en ella cualquier fichero que queramos que se incluya con la aplicación en tiempo de compilación en forma de recurso. Nosotros incluiremos como ejemplo un fichero de texto llamado «prueba_raw.txt«. Ya en tiempo de ejecución podremos acceder a este fichero, sólo en modo de lectura, de una forma similar a la que ya hemos visto para el resto de ficheros en memoria interna.

Para acceder al fichero, accederemos en primer lugar a los recursos de la aplicación con el método getResources() y sobre éstos utilizaremos el método openRawResource(id_del_recurso) para abrir el fichero en modo lectura. Este método devuelve un objeto InputStream, que ya podremos manipular como queramos mediante los métodos de la API java.io. Como ejemplo, nosotros convertiremos el stream en un objeto BufferedReader para leer el texto contenido en el fichero de ejemplo (por supuesto los ficheros de recurso también pueden ser binarios, como por ejemplo ficheros de imagen, video, etc). Veamos cómo quedaría el código:

try
{
	InputStream fraw =
		getResources().openRawResource(R.raw.prueba_raw);

	BufferedReader brin =
		new BufferedReader(new InputStreamReader(fraw));

	String linea = brin.readLine();

	fraw.close();
}
catch (Exception ex)
{
	Log.e("Ficheros", "Error al leer fichero desde recurso raw");
}

Como puede verse en el código anterior, al método openRawResource() le pasamos como parámetro el ID del fichero incluido como recurso, que seguirá el patrón «R.raw.nombre_del_fichero«, por lo que en nuestro caso particular será R.raw.prueba_raw.

La aplicación de ejemplo de este apartado consiste en una pantalla sencilla con 3 botones que realizan exactamente las tres tareas que hemos comentado: escribir y leer un fichero en la memoria interna, y leer un fichero de la carpeta raw.

Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la página del curso en GitHub.

Para no alargar mucho el artículo, dejamos la gestión de ficheros en la memoria externa para el próximo artículo.

Curso de Programación Android en PDF

Este curso también está disponible en PDF. Descubre cómo conseguirlo…

¿Te ha sido de utilidad el Curso de Programación Android? ¿Quieres colaborar de forma económica con el proyecto? Puedes contribuir con cualquier cantidad, unos céntimos, unos euros, cualquier aportación será bienvenida. Además, si tu aportación es superior a una pequeña cantidad simbólica recibirás como agradecimiento un documento con la última versión del curso disponible en formato PDF. Sea como sea, muchas gracias por colaborar!

Más información:

You may also like

28 comments

Desarrollo en Android | sgoliver.net blog 05/07/2011 - 13:01

[…] Ficheros en Android (I): Memoria Interna [Nuevo!] […]

Reply
Ficheros en Android (II): Memoria Externa (Tarjeta SD) | sgoliver.net blog 06/07/2011 - 11:17

[…] en Android (II): Memoria Externa (Tarjeta SD) sgoliver Móviles, Programación 2011-07-06 En el artículo anterior del curso hemos visto cómo manipular ficheros localizados en la memoria interna de un dispositivo […]

Reply
Miguel Angel 06/07/2011 - 18:15

Buenas lo primero mil gracias por desarrollar este blog de android que a los novatos nos viene genial y por sus publicaciones tan fáciles de entender. Ahora me surge una duda, usted pone que para almacenar en memoria interna la ruta es «/data/data/paquete_java/files/nombre_fichero» mi pregunta es que a mí la carpeta files no me sale, ¿tengo que crearla? Por defecto me sale una única carpeta que se llama lib.
Muchas gracias y saludos de un novato

Reply
Augusto 25/11/2011 - 16:59

Hola!!.

Ante todo deseo agradecerte por haber realizado este tutorial que es excelente. No soy programador profesional (no tengo titulo), y he aprendido a programar por gusto desde pequeño, y hace unos años retome por necesidad de la empresa.

He progamado en aspx en .net, .net para movile, aplacaciones de escritorio, etc. Pero es mi primera vez en Java, Eclipse, y Android, todo nuevo, todo a la vez. Realmente quisera hacerte algunas preguntas sencillas y conceptuales.

Agradecere si me envias un email para hacertelas, ya que no deseo ensuciar el foro.

Mil gracias desde Argentina

Reply
Alternativas para leer y escribir XML (y otros ficheros) en Android | sgoliver.net blog 25/01/2012 - 9:24

[…] memoria interna o externa tal como ya vimos en los artículos dedicados a tratamiento de ficheros (I y II). Esto quedaría de una forma similar a la […]

Reply
Dan CerBau 03/03/2012 - 22:21

Solo me deja una pregunta… ¿Cuál es la versión de Android que estás utilizando?
Por que yo, utilizo la versión 2.2 y no me deja usar la instrucción ‘openFileOutput(String, int)’
:-S

Gracias por tu atención y saludos desde México

Reply
admin 04/03/2012 - 13:46

Hola Dan CerBau, pues no sé cuál puede ser el problema exactamente, pero no me parece que sea del método openFileOutput(String,int). Según la documentación de Android este método existe desde la API 1 hasta la última versión (API 15). Debe tratarse de otro problema.

Reply
Shadowrun 30/03/2012 - 13:21

Buenas DANCERBAU. El problema es que OpenFileInput/Output se encuentran definidos solamente en la superclase CONTEXT
Las Activities y Services derivan de Context y ahí no tendrás problemas en usar esas funciones de acceso a ficheros. Pero si está en un Receiver, por ejemplo, no podrás utilizarlas a no ser que manejes alguna variable del tipo Context.
Hay varias posibilidades:
1.) Comunicarte con tu actividad principal y pedirle el context con algo parecido a «Context ctx=getApplicationContext();»
2.) Si desde una actividad lanzaste un Intent hacia el Receiver, pues meter dentro del Intent la variable Context. Entonces el Receiver ya podrá trabajar con ese CONTEXT sin problemas.

Un saludete.

Reply
Sebastián 12/05/2012 - 23:17

A mi tampoco me permite usar el método openFileOutput(…) no se cual será el problema.
Saludos,
Sebastián

Reply
Juan 06/07/2012 - 1:16

es posible crear un archivo .xls o .pdf??

Reply
TePreguntoATi 06/07/2012 - 4:57

He tio, mira necesito que me digas que programa haz usado para Acceder a la memoria interna del dispositivo (Android) porfavor necesito un link necesito hacer un…proyecto…

Gracias de Antemano!

Reply
Alberto 07/10/2012 - 19:56

Mi problema es el siguiente:

tengo una función que lee de un fichero que está en el programa e inserta cadenas a un List. El problema es que, cuando recorro esta lista, voy haciendo comparaciones entre cadenas y aquellas que deberían coincidir (y de hecho coinciden si ejecuto la función desde un programa java) en el programa Android no coinciden.

¿Acaso el readLine le cambia la codificación o algo extraño?

Estoy usando el openRawResource para obtener el InputStream.

P.S.: ya sé que mi error es algo extraño de explicar, pero no se me ocurría cómo sin poner mucho código.

Reply
sgoliver 07/10/2012 - 23:26

¿como estas comparando las cadenas? ¿podrías poner algún fragmento de código para entender mejor el problema? Y si lo haces en el foro mejor que aquí en los comentarios. Gracias.

Reply
androidgo 12/10/2012 - 14:42

buenas, estoy intentando leer un arxivo y colocar lo q hay en el arxivo en los diferentes campos d texto para ello e utilizado este codigo, pero no funciona a ver si me podrian ayudar
botoRecuperarLlista.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try{
BufferedReader inputReader = new BufferedReader(new InputStreamReader
(openFileInput(«llistaCompra.txt»)));
String []llista = new String [200];
String linia = inputReader.readLine();
StringBuffer sBuffer = new StringBuffer();
while((linia!= null)){
for(int i=0;i<linia.length();i++){
llista[i]=inputReader.readLine();
}
txt1.setText(sBuffer.append(llista[0]));
txt2.setText(sBuffer.append(llista[1]));
txt3.setText(sBuffer.append(llista[2]));
txt4.setText(sBuffer.append(llista[3]));
}

}
catch(FileNotFoundException e){

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
});

Reply
Kivpson 14/10/2012 - 20:08

El problema con openFileOutput() se da cuando se utiliza en una clase fuera el Activity, sin embargo es posible pasarla como parámetro a alguna clase que hayamos definido y utilizarlo sin problema, por dar un ejemplo:

// CLASE EJEMPLO

public class DataFile {

public String getData(Context context){
String file_name = «mi_archivo.txt»;

try{
InputStreamReader file = new InputStreamReader(context.getApplicationContext().openFileInput(file_name));
BufferedReader br = new BufferedReader( file );

String texto = br.readLine();
br.close();

return texto;

}catch (IOException e){
Log.e(«FILE_MANAGER», «getData: Error al leer fichero desde memoria interna»);
return «»;
}
}

}

// LLAMADO DENTRO DE UN ACTIVITY
DataFile manager = new DataFile();
String datos_en_archivo = manager.getData(NombreActivity.this);

Saludos.

Reply
Hary 18/02/2013 - 22:43

Hola quisiera saber como podria hacer para modificar ficheros ya se como es !! pero para que me funcione como usuario root! me refiero a modificar un fichero ubicado en /system o algo asi

Reply
Hary 19/02/2013 - 21:08

Hola yo de nuevo quisiera saber como hacer para mostrar el texto leido de un fichero en un textview?

Reply
alberto 21/04/2013 - 12:53

¿Como hago para recorrer todos los archivos del directorio files por que uno esta claro como es pero todos?

Reply
marco 27/12/2013 - 23:39

Hola mi pregunta es como compartir archivo de audio que tengo en la carpeta raw de recursos con por ejemplo a whassap a través de un
intent.
Intent i = new Intent (Intent. ACTION_SEND);
i.setType(«audio/mp3);
i.putExtra(Intent. EXTRA_STREAM, Uri.pares(«android.resource://con.ejemplo.sonidos/» + R.raw.claxon);
startActivity(Intent.createChooser(i, «sonido mandado»);

Reply
alavaros 15/03/2014 - 14:30

Buenas, primero felicitarte por el blog, nos ayuda muchísimo a los principiantes en Android.

Estoy desarrollando una aplicación que tendrá la posibilidad de hacer fotos, la idea es hacer la foto, rellenar otros datos, y pulsar en un botón para enviar toda la información, incluida la foto, vía web service a un servidor. ¿Dónde debo guardar/almacenar/cachear la/las foto/s antes de enviarla? ¿Interna, Externa o Cache?. Leyendo creo que, y corrígeme si me equivoco, puedo descartar cache, puesto que no tiene demasiado tamaño de almacenamiento, no es así? Por otro lado me gustaría que las fotos fueran solo accesibles a mi aplicación, pero tampoco me quiero quedar corto de espacio, luego ¿donde crees que debo almacenarlo?

Muchas gracias de antemano.

Reply
Gabriel 14/04/2014 - 19:29

Mis felicitaciones por el foro, está muy pero muy bueno, lamento no manejar la programación en android. Cuento un poco, he programado en varios lenguajes.. HTML, HTML5, php, visual, VBA.

Necesito una mano.. he realizado un programa en flash y necesito hacer llamado a las aplicaciones que tiene android como por ejemplo.. lanzar el reloj o cualquier aplicación que tenga instalada en android, el tema es que podría hacerlo si supiera la ruta del escritorio de android.. he revisado pero no encuentro bien el path.. del escritorio y que tipo de extensión tienen los íconos del escritorio en android..

Agradesco muchísimo alguien me escriba al mail.. indicandome el path.. del escritorio y que extensión tiene los íconos. (yo haría un llamado mediante un vínculo a uno de los íconos del escritorio para lanzar el programa deseado).-

Desde ya muchísimas gracias..

GABRIEL.-

Reply
ezze 15/06/2014 - 23:25

hola me podrias ayudar modifique un archivo de la memoria interna el archivo vold.fstab y ahora no me la reconoce y no se que hacer para que la vuelva a reconocer

Reply
Saragut 27/06/2014 - 8:16

Hola, quiero descargar un archivo desde una URL y lo quiero dejar en la carpeta res/raw, como podría hacerlo? Sé como descargarlo a la sd pero no a la carpeta de recursos de la aplicación.

Muchas gracias de antemano! Felicidades por el blog, lo consulto a menudo y me ha sacado de bastantes apuros :-)

Reply
programador000 07/08/2014 - 20:33

Hola amigo, me parecio muy util la info y me funciona a la perfeccion…. pero tengo una duda:
hay alguna forma de hacer que lo guarde dentro de otra carpeta?? (es decir /data/data/paquete.java/files/Nueva_Carpeta/nombre_fichero)

Reply
Alberto 21/08/2014 - 22:07

Hola me parece un articulo interesante pero tengo duda con 2 cosas:

1.- Se podran subir archivo con extencion 3dmlm?

2.- Hay algun modo de poder grabar y guardar una cancion o un audio(mp3, etc)?

Espero me puedas ayudar

Reply
Curso Programación Android por Salvador Gómez – Indice de Contenidos | Miguel Moyetones 17/06/2015 - 21:25

[…] Ficheros en Android (I): Memoria Interna [v3] […]

Reply
Félix 20/08/2015 - 12:59

Hola, me parece muy interesante esta web de la que se aprenden muchisimas cosas.
Necesito ayuda para una aplicación que estoy haciendo y hace uso de un fichero XML. Tengo varias opciones desde donde usar dicho fichero y que funcionan perfectamente:
– desde un recurso local – carpeta raw (pero que así no se podría actualizar dicho fichero)
– desde una URL, leyendo el archivo online (siempre estaría actualizado, pero habría que leer siempre el fichero y tener conexión a datos)

Pero querría otra solución mucho más efectiva que es bajar el fichero desde una URL con una tarea en segundo plano y copiarlo en el dispositivo para usarlo mientras no sufra modificaciones en origen.

El PROBLEMA es que solo habría que bajar el fichero si ha sufrido modificación respecto al fichero grabado en el dispositivo la última vez y no se como comprobar si son ficheros distintos para decidir si debo bajarlo o no de la URL.

Gracias.

Reply
Gianfranco 08/07/2016 - 18:46

Hola, que tal? he creado un aplicativo y que me genera un txt, pero el problema es que cuando instalo el apk, no me crea el paquete, como por ejemplo com.facebook.net, el mio no lo crea y no se si se tiene que agregar algún comando o línea de código para crear ese paquete en mi celular. Gracias

Reply

Leave a Comment

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies