Passer au contenu principal

📁 Entrées/Sorties de Fichiers

📖 Qu'est-ce que les Entrées/Sorties de Fichiers ?

Les Entrées/Sorties de Fichiers (File I/O) correspondent aux opérations de lecture et d'écriture de fichiers. Elles sont essentielles pour le stockage de données, la gestion de configuration, l'enregistrement de logs, etc. !

💡 Lecture de Fichiers

Lecture Complète

import java.io.File

fun main() {
// Lire tout le fichier sous forme de chaîne
val content = File("data.txt").readText()
println(content)

// Lire le fichier sous forme de liste de lignes
val lines = File("data.txt").readLines()
for (line in lines) {
println(line)
}
}

Lecture Sécurisée

import java.io.File

fun readFileSafe(filename: String): String? {
return try {
File(filename).readText()
} catch (e: Exception) {
println("Échec de la lecture du fichier : ${e.message}")
null
}
}

fun main() {
val content = readFileSafe("data.txt")
if (content != null) {
println("Contenu : $content")
} else {
println("Impossible de lire le fichier")
}
}

Traitement Ligne par Ligne

import java.io.File

fun main() {
// Efficace en mémoire (idéal pour les gros fichiers)
File("data.txt").forEachLine { line ->
println(line)
}

// useLines - fermeture automatique
val lineCount = File("data.txt").useLines { lines ->
lines.count()
}
println("Nombre total de lignes : $lineCount")
}

✏️ Écriture de Fichiers

Réécriture

import java.io.File

fun main() {
// Écrire du texte
File("output.txt").writeText("Bonjour\nC'est Kotlin !")

// Écrire ligne par ligne
val lines = listOf("Première ligne", "Deuxième ligne", "Troisième ligne")
File("output.txt").writeText(lines.joinToString("\n"))
}

Ajout

import java.io.File

fun main() {
val file = File("log.txt")

// Ajouter du contenu
file.appendText("Log 1\n")
file.appendText("Log 2\n")
file.appendText("Log 3\n")
}

Écriture Sécurisée

import java.io.File

fun writeFileSafe(filename: String, content: String): Boolean {
return try {
File(filename).writeText(content)
true
} catch (e: Exception) {
println("Échec de l'écriture du fichier : ${e.message}")
false
}
}

fun main() {
if (writeFileSafe("data.txt", "Hello Kotlin!")) {
println("Fichier enregistré avec succès")
}
}

🎯 Exemples Pratiques

Bloc-Notes Simple

import java.io.File

class SimpleNotebook(private val filename: String) {
private val file = File(filename)

fun write(content: String) {
file.writeText(content)
println("Enregistrement terminé")
}

fun append(content: String) {
file.appendText("$content\n")
println("Ajout terminé")
}

fun read(): String {
return if (file.exists()) {
file.readText()
} else {
"Fichier inexistant"
}
}

fun clear() {
file.writeText("")
println("Contenu supprimé")
}
}

fun main() {
val notebook = SimpleNotebook("mynotes.txt")

notebook.write("Première note")
notebook.append("Deuxième note")
notebook.append("Troisième note")

println("\n=== Contenu du bloc-notes ===")
println(notebook.read())
}

Enregistreur de Logs

import java.io.File
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

class Logger(private val filename: String) {
private val file = File(filename)
private val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")

fun log(message: String) {
val timestamp = LocalDateTime.now().format(formatter)
file.appendText("[$timestamp] $message\n")
}

fun info(message: String) = log("INFO: $message")
fun error(message: String) = log("ERROR: $message")
fun warn(message: String) = log("WARN: $message")

fun readLogs(): String {
return if (file.exists()) {
file.readText()
} else {
"Aucun log"
}
}
}

fun main() {
val logger = Logger("app.log")

logger.info("Démarrage de l'application")
logger.warn("Mémoire insuffisante")
logger.error("Échec de la connexion")

println(logger.readLogs())
}

Traitement de Fichiers CSV

import java.io.File

data class Person(val name: String, val age: Int, val city: String)

object CsvHandler {
fun writeCsv(filename: String, people: List<Person>) {
val csv = StringBuilder()
csv.append("Nom,Âge,Ville\n")

for (person in people) {
csv.append("${person.name},${person.age},${person.city}\n")
}

File(filename).writeText(csv.toString())
}

fun readCsv(filename: String): List<Person> {
val file = File(filename)
if (!file.exists()) return emptyList()

val lines = file.readLines()
if (lines.isEmpty()) return emptyList()

return lines.drop(1).map { line ->
val parts = line.split(",")
Person(parts[0], parts[1].toInt(), parts[2])
}
}
}

fun main() {
val people = listOf(
Person("Hong Gildong", 25, "Séoul"),
Person("Kim Chulsoo", 30, "Busan"),
Person("Lee Younghee", 28, "Daegu")
)

// Enregistrer le CSV
CsvHandler.writeCsv("people.csv", people)
println("CSV enregistré avec succès")

// Lire le CSV
val loaded = CsvHandler.readCsv("people.csv")
println("\n=== Contenu du CSV ===")
loaded.forEach { println(it) }
}

Gestion de Fichier de Configuration

import java.io.File

class Config(private val filename: String) {
private val settings = mutableMapOf<String, String>()

init {
load()
}

private fun load() {
val file = File(filename)
if (file.exists()) {
file.forEachLine { line ->
val parts = line.split("=")
if (parts.size == 2) {
settings[parts[0].trim()] = parts[1].trim()
}
}
}
}

fun save() {
val content = settings.entries.joinToString("\n") {
"${it.key}=${it.value}"
}
File(filename).writeText(content)
}

fun set(key: String, value: String) {
settings[key] = value
}

fun get(key: String): String? {
return settings[key]
}

fun getAll(): Map<String, String> {
return settings.toMap()
}
}

fun main() {
val config = Config("app.config")

// Enregistrer la configuration
config.set("host", "localhost")
config.set("port", "8080")
config.set("timeout", "3000")
config.save()

// Lire la configuration
println("Host : ${config.get("host")}")
println("Port : ${config.get("port")}")

println("\n=== Configuration complète ===")
config.getAll().forEach { (key, value) ->
println("$key = $value")
}
}

📂 Gestion de Fichiers/Répertoires

Informations sur les Fichiers

import java.io.File

fun main() {
val file = File("data.txt")

println("Existe : ${file.exists()}")
println("Fichier : ${file.isFile}")
println("Répertoire : ${file.isDirectory}")
println("Taille : ${file.length()} octets")
println("Chemin absolu : ${file.absolutePath}")
println("Nom : ${file.name}")
println("Dossier parent : ${file.parent}")
}

Opérations sur les Répertoires

import java.io.File

fun main() {
// Créer un répertoire
val dir = File("mydata")
dir.mkdir()

// Liste des fichiers
dir.listFiles()?.forEach { file ->
println("${file.name} (${if (file.isDirectory) "dossier" else "fichier"})")
}

// Rechercher les fichiers dans les sous-dossiers
dir.walk().forEach { file ->
println(file.absolutePath)
}
}

Copie/Suppression de Fichiers

import java.io.File

fun main() {
val source = File("source.txt")
val dest = File("dest.txt")

// Copier
source.copyTo(dest, overwrite = true)

// Déplacer
source.renameTo(File("moved.txt"))

// Supprimer
dest.delete()

// Supprimer tout un répertoire
File("mydata").deleteRecursively()
}

🤔 Questions Fréquentes

Q1. Que faire si le fichier n'existe pas ?

R : La gestion des exceptions est essentielle !

fun readFileSafe(filename: String): String {
val file = File(filename)

if (!file.exists()) {
return "Fichier inexistant"
}

return try {
file.readText()
} catch (e: Exception) {
"Échec de la lecture : ${e.message}"
}
}

Q2. Comment traiter les gros fichiers ?

R : Traitez-les ligne par ligne !

// ❌ Risque de manque de mémoire
val content = File("huge.txt").readText()

// ✅ Traitement ligne par ligne
File("huge.txt").forEachLine { line ->
processLine(line)
}

Q3. Quel séparateur de chemin utiliser ?

R : Utilisez File.separator !

// ❌ Différent selon l'OS
val path = "data/files/text.txt"

// ✅ Indépendant de l'OS
val file = File("data", "files").resolve("text.txt")
// ou
val path2 = listOf("data", "files", "text.txt").joinToString(File.separator)

🎬 Conclusion

Stockez et gérez vos données avec les entrées/sorties de fichiers !

Points clés :
✅ Lisez les fichiers avec readText()
✅ Écrivez les fichiers avec writeText()
✅ Traitez ligne par ligne avec forEachLine()
✅ Vérifiez l'existence avec exists()
✅ La gestion des exceptions est essentielle

Prochaine étape : Découvrez le filtrage par motifs avec Expressions Régulières !