Como ler um arquivo de texto da pasta resources em Kotlin: tutorial passo a passo
\n\nOlá, amigo! Se você já programou em Kotlin para Android ou criou um aplicativo de console, certamente já enfrentou uma tarefa simples, mas traiçoeira: como ler um arquivo de texto que está na pasta resources? Parece simples, não? Mas se você der uma olhada no Stack Overflow, a pergunta "How to read a text file from resources in Kotlin?" tem milhares de visualizações. Isso significa que o problema é real.
Neste artigo, vamos explorar 5 maneiras confiáveis de fazer isso. Você aprenderá a diferença entre javaClass e ClassLoader, como evitar um NullPointerException e o que fazer se seu projeto for uma biblioteca, e não um aplicativo. Vamos lá!
1. Preparação: onde colocar o arquivo?
\nAntes de ler, o arquivo precisa ser colocado no local correto. Em um projeto Kotlin padrão (Gradle, Maven), a pasta de recursos geralmente está aqui:
\n\nsrc/main/resources/\n\nPara testes — src/test/resources/. Se você tem um projeto Android, os recursos são colocados em src/main/res/raw/ (mas a lógica é diferente, falaremos disso mais adiante). Vamos nos concentrar no Kotlin/JVM puro.
Vamos criar um arquivo simples data.txt com o conteúdo:
Olá, mundo!\nEstas são linhas dos recursos.\nKotlin manda.\n\nÓtimo, a ferramenta está pronta. Agora vamos ver como abri-lo.
\n\n2. Método nº1: O clássico via javaClass
\nA maneira mais popular e intuitiva é usar javaClass (que é o wrapper Kotlin para getClass() em Java).
import java.io.File\n\nfun readFromResources(fileName: String): String {\n val inputStream = this::class.java.classLoader?.getResourceAsStream(fileName)\n ?: throw IllegalArgumentException("Arquivo $fileName não encontrado nos recursos")\n return inputStream.bufferedReader().readText()\n}\n\nAnálise detalhada:
\n- \n
this::class.java— obtém a classe Java do objeto atual. \n .classLoader— pega o ClassLoader (carregador de classes). \n getResourceAsStream(fileName)— abre o fluxo. \n - O operador Elvis
?:lança uma exceção se o arquivo não existir. \n
Chamamos:
\nfun main() {\n val content = readFromResources("data.txt")\n println(content)\n}\n\nNa saída, veremos as três linhas do nosso arquivo. Simples e elegante.
\n\n3. Método nº2: Usando object para utilitários
\nSe você está escrevendo uma classe utilitária, é conveniente colocar a lógica em um object (singleton). Em Kotlin, fazemos assim:
object ResourceReader {\n fun readText(fileName: String): String {\n val stream = ResourceReader::class.java.classLoader\n .getResourceAsStream(fileName)\n ?: throw FileNotFoundException("Recurso $fileName não 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\nObserve: usamos ResourceReader::class.java — isso funciona porque object é um singleton que possui uma classe.
4. Método nº3: Lendo como URL (para obter o caminho)
\nÀs vezes, você precisa não do conteúdo, mas do caminho do arquivo (por exemplo, para passar para outra biblioteca). Nesse caso, usamos getResource():
fun getResourcePath(fileName: String): String {\n val url = this::class.java.classLoader.getResource(fileName)\n ?: throw RuntimeException("Recurso $fileName não encontrado")\n return url.path\n}\n\nMas tenha cuidado: se o projeto estiver empacotado em um JAR, url.path pode apontar para dentro do arquivo, e o File não conseguirá lê-lo. Nesse caso, é melhor usar sempre o fluxo (