Cómo leer un archivo de texto desde la carpeta resources en Kotlin: tutorial paso a paso
\n\n¡Hola, amigo! Si alguna vez has programado en Kotlin para Android o simplemente has creado una aplicación de consola, seguro te has encontrado con una tarea simple pero engañosa: ¿cómo leer un archivo de texto que está en la carpeta resources? Parecería que no tiene mucha ciencia, ¿verdad? Pero si miras en Stack Overflow, la pregunta "How to read a text file from resources in Kotlin?" acumula miles de visitas. Eso significa que el problema es real.
En este artículo, analizaremos 5 formas fiables de hacerlo. Aprenderás la diferencia entre javaClass y ClassLoader, cómo evitar un NullPointerException y qué hacer si tu proyecto es una biblioteca y no una aplicación. ¡Allá vamos!
1. Preparación: ¿dónde colocar el archivo?
\nAntes de leer, hay que poner el archivo en el lugar correcto. En un proyecto Kotlin estándar (Gradle, Maven), la carpeta para recursos suele estar aquí:
\n\nsrc/main/resources/\n\nPara pruebas — src/test/resources/. Si tienes un proyecto de Android, los recursos se colocan en src/main/res/raw/ (pero ahí tiene su propia lógica, lo veremos más adelante). Nos centraremos en Kotlin/JVM puro.
Creemos un archivo simple data.txt con el siguiente contenido:
¡Hola, mundo!\nEstas son líneas desde los recursos.\nKotlin mola.\n\nPerfecto, la herramienta está lista. Ahora veamos cómo abrirlo.
\n\n2. Método n.º 1: El clásico mediante javaClass
\nLa forma más popular e intuitiva es usar javaClass (es el envoltorio de Kotlin para getClass() en Java).
import java.io.File\n\nfun readFromResources(fileName: String): String {\n val inputStream = this::class.java.classLoader?.getResourceAsStream(fileName)\n ?: throw IllegalArgumentException("Archivo $fileName no encontrado en recursos")\n return inputStream.bufferedReader().readText()\n}\n\nAnálisis detallado:
\n- \n
this::class.java— obtenemos la clase Java del objeto actual. \n .classLoader— tomamos el ClassLoader (cargador de clases). \n getResourceAsStream(fileName)— abrimos el flujo. \n - El operador Elvis
?:lanza una excepción si el archivo no existe. \n
Lo llamamos:
\nfun main() {\n val content = readFromResources("data.txt")\n println(content)\n}\n\nEn la salida veremos las tres líneas de nuestro archivo. Simple y elegante.
\n\n3. Método n.º 2: Usamos object para utilidades
\nSi estás escribiendo una clase de utilidades, es conveniente mover la lógica a un object (singleton). En Kotlin se hace así:
object ResourceReader {\n fun readText(fileName: String): String {\n val stream = ResourceReader::class.java.classLoader\n .getResourceAsStream(fileName)\n ?: throw FileNotFoundException("Recurso $fileName no encontrado")\n return stream.bufferedReader().readText()\n }\n}\n\n// Uso:\nfun main() {\n val text = ResourceReader.readText("config.json")\n println(text)\n}\n\nObserva: usamos ResourceReader::class.java — esto funciona porque object es un singleton que tiene una clase.
4. Método n.º 3: Leer como URL (para obtener la ruta)
\nA veces no necesitas el contenido, sino la ruta al archivo (por ejemplo, para pasarlo a otra biblioteca). Entonces usamos getResource():
fun getResourcePath(fileName: String): String {\n val url = this::class.java.classLoader.getResource(fileName)\n ?: throw RuntimeException("Recurso $fileName no encontrado")\n return url.path\n}\n\nPero ten cuidado: si el proyecto está empaquetado en un JAR, url.path puede apuntar al interior del archivo, y File no podrá leerlo. En ese caso, es mejor usar siempre el flujo (