1. Introduzione
Immagina di ricevere dal contabile un file con un report salvato in "Windows-1251" (vecchia codifica per il cirillico). La tua applicazione Java si aspetta tutti i dati di input in "UTF-8", altrimenti inizia a dare errori e a mostrare caratteri illeggibili al posto delle lettere. Oppure, ad esempio, ti integri con un sistema che accetta solo "ISO-8859-1". Che fare? Naturalmente, ricodificare il file!
Ricodifica — è il processo con cui leggi il testo da un file in una codifica e lo salvi in un'altra. È come riscrivere una lettera da una lingua a un'altra, affinché il destinatario capisca esattamente il tuo messaggio.
Come funziona la ricodifica in Java: approccio generale
In Java le stringhe (String) all'interno del programma sono sempre memorizzate in Unicode (UTF‑16). Significa che, una volta letto il testo da un file, è già “universale” e può essere scritto in qualsiasi codifica supportata. Pertanto, la ricodifica è semplicemente:
- Leggere il file come stringhe, indicando la codifica di origine corretta.
- Scrivere queste stringhe in un nuovo file, indicando esplicitamente la codifica di destinazione desiderata.
Schema:
[File in codifica A] --(lettura con Charset A)--> [String in memoria] --(scrittura con Charset B)--> [File in codifica B]
2. Algoritmo passo‑passo per la ricodifica
Passaggio 1. Determinare la codifica di origine e quella di destinazione
La codifica di origine è quella in cui è stato salvato il file iniziale (ad esempio, "Windows-1251"). La codifica di destinazione è quella in cui vuoi ottenere il risultato (ad esempio, "UTF-8").
Passaggio 2. Aprire lo stream di lettura con la codifica necessaria
Usiamo Files.newBufferedReader(Path, Charset) oppure il classico InputStreamReader.
Passaggio 3. Aprire lo stream di scrittura con la codifica necessaria
Usiamo Files.newBufferedWriter(Path, Charset) oppure il classico OutputStreamWriter.
Passaggio 4. Leggere le righe e scriverle nel nuovo file
Leggiamo riga per riga (o tutto in una volta — se il file è piccolo) e scriviamo ogni riga nel nuovo file.
Passaggio 5. Chiudere gli stream (meglio usare try-with-resources)
Così garantiamo il corretto rilascio delle risorse. Usa la costruzione try-with-resources.
3. Esempio di codice: ricodifica Windows-1251 → UTF-8
Realizziamo un semplice programma che ricodifica un file da Windows‑1251 a UTF‑8. Un esempio del genere è comune nella vita reale, soprattutto se lavori con dati in lingua russa.
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
public class FileReencoder {
public static void main(String[] args) throws IOException {
// Percorsi dei file
Path inputPath = Paths.get("input-1251.txt");
Path outputPath = Paths.get("output-utf8.txt");
// Apriamo un reader con la codifica di origine Windows-1251
try (
BufferedReader reader = Files.newBufferedReader(inputPath, Charset.forName("Windows-1251"));
BufferedWriter writer = Files.newBufferedWriter(outputPath, StandardCharsets.UTF_8)
) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine(); // non dimentichiamo l'andata a capo!
}
}
System.out.println("File ricodificato correttamente da Windows-1251 a UTF-8!");
}
}
Qui specifichiamo esplicitamente la codifica per la lettura (Charset.forName("Windows-1251")) e per la scrittura (StandardCharsets.UTF_8). Poi utilizziamo try-with-resources così che gli stream si chiudano automaticamente anche in caso di errore. writer.newLine() — a capo, per preservare la struttura del file.
4. Dettagli importanti e consigli pratici
Come capire la codifica di origine del file?
- Il file di per sé non contiene un “cartellino” con l'indicazione della codifica (eccezione: BOM, ma non sempre è presente).
- Se il file l'hai creato tu — usa la stessa codifica che hai usato in scrittura.
- Se il file è arrivato “da qualche parte” — prova ad aprirlo in un editor che mostra la codifica (ad esempio, Notepad++, Visual Studio Code).
- In Linux puoi usare il comando file -i nome_file, ma non sempre individua correttamente la codifica.
Cosa succede se si indica una codifica di origine errata?
Otterrai caratteri illeggibili (mojibake) o perdita di simboli. Ad esempio, se leggi un file salvato in Windows‑1251 come UTF‑8, il cirillico si trasformerà in "Привет".
Gestione delle eccezioni
Quando si lavora con i file, gli errori sono sempre possibili: file non trovato, permessi assenti, codifica errata. Usa la gestione delle eccezioni (try-catch) o rilanciale verso l'alto (throws), in modo che l'applicazione non vada in crash “senza spiegazioni”.
Lavorare con file grandi
Se il file è enorme (gigabyte!), usa la lettura e la scrittura riga per riga, come negli esempi riportati. Non leggere l'intero file in memoria — altrimenti otterrai un OutOfMemoryError.
Ricodifica “al volo” (streaming)
Se il file è molto grande, puoi anche evitare di creare un file intermedio e leggere/scrivere “al volo” — ad esempio, durante l'elaborazione in streaming di dati dalla rete.
5. Errori tipici durante la ricodifica dei file
Errore n. 1: Codifica di origine errata. Se sbagli la codifica di origine, il risultato sarà pessimo: “Privet” si trasformerà in "Привет". Verifica sempre in quale codifica è stato creato il file.
Errore n. 2: Uso implicito della codifica di sistema. Se non specifichi esplicitamente la codifica, Java utilizza quella di sistema predefinita (System.getProperty("file.encoding")). Questo può portare a risultati diversi su computer diversi (ad esempio, su Windows — cp1251, su Linux — UTF‑8).
Errore n. 3: Lettura e scrittura dell'intero file in memoria. Per file grandi questo approccio porta all'esaurimento della memoria. Usa la lettura e la scrittura riga per riga.
Errore n. 4: Eccezioni non gestite. I file possono non esistere, essere occupati da altri processi o contenere caratteri corrotti. Gestisci sempre le eccezioni oppure utilizza try-with-resources.
Errore n. 5: Ricodifica di file binari. Non tentare di ricodificare immagini, PDF, archivi e altri file binari! Ciò li danneggerà. La ricodifica ha senso solo per i file di testo.
GO TO FULL VERSION