Codifica caratteri

di il
6 risposte

Codifica caratteri

Sto scrivendo un programma che analizza delle pagine web e ne estrae il contenuto in base a certe regole. Il contenuto estratto viene scritto in un file di testo.
Lo sviluppo lo faccio su Linux con Java 8 e jSoup e tutto fila liscio; soprattutto il file di testo e' interamente leggibile. Se lo lancio su Windows tutti i caratteri non ascii vengono codificati con delle pernacchie o simili. Se lo apro con NotePad il contenuto e' tutto su una riga, con WordPad e' impaginato bene ma i caratteri non ascii sono illeggbili, stessa cosa da linea di comando con more.

Come faccio a scrivere del testo con lettere accentate e caratteri tipografici in file di testo leggibili anche sotto Windows?

Devo usare qualche magia sotto Java o il problema e' risolvibile in altro modo?

Grazie

6 Risposte

  • Re: Codifica caratteri

    Ho provato nel frattempo un paio di codifiche (UTF-8 e ISO-8839-1) che non risolvono completamente il problema:
    FileOutputStream fw = new FileOutputStream(file.getAbsoluteFile());
    OutputStreamWriter bw = new OutputStreamWriter(fw, "ISO-8859-1");

    Con UTF-8 i caratteri tipografici si leggono bene sotto Linux ma non sotto Windows. Con ISO-8839-1 su Linux non si leggono mentre su Windows migliora la lettura ma apici e doppi apici vengono codificati come ?-
  • Re: Codifica caratteri

    Le questioni su charset sono spesso rognose, perché possono capitare a più livelli, coinvolgendo software vari, sistema operativo e altro. E talvolta capitano perché magari si trattano byte/char in modo inappropriato. Partiamo dall'inizio.

    Punto uno: la pagina web (HTML) a cui stai cercando di accedere è codificata in un certo charset. Qui intendo la codifica fisica dei caratteri nei byte dello stream. Quale sia nel tuo caso non l'hai precisato.
    A seguito della request, nella response inviata dal server dovrebbe esserci l'header Content-Type che oltre al MIME type dovrebbe anche specificare il charset. Es. "text/html; charset=iso-8859-1"

    Fin qui si deve presupporre che la codifica fisica caratteri->byte corrisponda a quella indicata nel Content-Type e che sia corretta. Se già questo non fosse vero, allora sarebbe già un primo problema.

    Punto due: stai usando jsoup. Non lo conosco, mai usato ma so che è un parser HTML in Java. Immagino (e mi auguro) che a fronte di un URL sottoposto a jsoup, esso faccia la cosa giusta, deducendo il giusto charset e decodificando quindi la sequenza di byte nella giusta sequenza di caratteri. E poi ti fornisce gli oggetti String corretti per contenuti, attributi, ecc...

    Se gli oggetti String sono corretti (questo lo puoi verificare tu, magari in debugging), allora ok. Altrimenti sarebbe un ulteriore problema.

    Punto tre: vuoi scrivere delle stringhe su file. Qui ci sono di nuovo questioni sui charset. Nel senso che puoi decidere di usare implicitamente il charset della piattaforma (qualunque esso sia) usando FileWriter. Oppure esplicitare un charset specifico usando la classe di adapter OutputStreamWriter oppure con PrintStream o PrintWriter a cui si può passare il nome di un charset.

    Punto quattro: se vuoi aprire il file generato con un editor di testo, devi assicurarti che l'editor sia in grado di usare quel certo charset. Su Windows il charset predefinito della piattaforma tipicamente è il Windows-1252 che è un superset del ISO-8859-1. Con il notepad di Windows non ci sono problemi a leggerlo. Con altri editor, dipende.

    E comunque devi anche valutare tu cosa ti aspetti che ci sia nel documento. Se la pagina fornisce tutto corretto in UTF-8 e poi tu scrivi un file in ISO-8859-1, allora è assolutamente possibile che qualcosa si "perda".

    Comunque devi precisare qualcosa di più se vuoi ottenere qualche aiuto in più.
  • Re: Codifica caratteri

    Grazie della risposta esauriente. Dunque partiamo dall'inizio. jSoup e' un parser di pagine HTML con un filtering simil jQuery, per cui, conoscendo quest'ultimo, e' molto semplice da usare.
    Il risultato delle query sono in formato String che paiono corretti dato che sia nella finestra di output di IntelliJ che su terminale i caratteri vengono stampati correttamente.

    La codifica delle pagine web e' content="text/html; charset=UTF-8"

    All'inizio usavo semplicemente FileWriter perche' su Linux i caratteri sia a schermo che nel file di testo erano corretti. Facendolo girare su Windows i caratteri tipografici e le accentate non venivano riconosciute (ne' con more, ne' con NotePad, ne' con WordPad).

    Allora ho provato con OutputStreamWriter provando a modificare il charset (p.e. ISO-8859-1), ma con scarsi risultato. Come riportato in precedenza, alcuni caratteri tipografici non vengono comunque interpretati da Windows (e con ISO-8850-1 neanche da Linux). Comunque il programma dovra' girare principalmente su Windows per cui e' lui la priorita'.

    Spero di aver chiarito tutto.
    Grazie
  • Re: Codifica caratteri

    morellik ha scritto:


    Il risultato delle query sono in formato String che paiono corretti dato che sia nella finestra di output di IntelliJ che su terminale i caratteri vengono stampati correttamente.

    La codifica delle pagine web e' content="text/html; charset=UTF-8"
    Allora si presuppone che perlomeno fin qui sia tutto corretto, sia dal server, dalla pagina e dalla elaborazione di jsoup.

    morellik ha scritto:


    All'inizio usavo semplicemente FileWriter perche' su Linux i caratteri sia a schermo che nel file di testo erano corretti. Facendolo girare su Windows i caratteri tipografici e le accentate non venivano riconosciute (ne' con more, ne' con NotePad, ne' con WordPad).

    Allora ho provato con OutputStreamWriter provando a modificare il charset (p.e. ISO-8859-1), ma con scarsi risultato. Come riportato in precedenza, alcuni caratteri tipografici non vengono comunque interpretati da Windows (e con ISO-8850-1 neanche da Linux).
    Ma dipende quali caratteri devi trattare! ISO-8859-1 è molto ristretto rispetto al Unicode, dato che gli ISO-8859-xx sono single-byte quindi max 256 caratteri.

    Se ad esempio dovessi rappresentare il carattere del per mille ‰ in ISO-8859-1 semplicemente non c'è, non è rappresentabile. Quindi o scegli un altro charset oppure fai qualche trasformazione di caratteri lato java prima di scrivere.

    E poi comunque, ripeto, dipende anche dal editor e font usati. Anche se scrivessi su file tutto corretto ma poi apri il file con un editor di testo che usa ... che so, un font Courier limitato che non ha i glyph (la figura di un carattere) per i caratteri particolari che sono stati usati, idem potresti vedere un blocchetto nero o altro.
  • Re: Codifica caratteri

    Ok, grazie. Quindi mi pare di aver capito che non c'e' una soluzione definitiva. Ci sono troppe variabili nel mezzo. Provero' varie codifiche e apriro' il file con Word che spero abbia tutti i set di caratteri.
  • Re: Codifica caratteri

    morellik ha scritto:


    Quindi mi pare di aver capito che non c'e' una soluzione definitiva.
    La soluzione generale per la codifica dei caratteri esiste: Unicode
    È stato creato apposta per superare tutte le menate dei charset single byte.

    morellik ha scritto:


    Provero' varie codifiche e apriro' il file con Word che spero abbia tutti i set di caratteri.
    Puoi anche provare altri charset ma resta il fatto che se un editor apre un file di testo puro codificato con un certo charset, deve essere l'utente a specificare quale è questo charset. In generale non è possibile "dedurre" facilmente in modo programmatico il charset ... a meno di casi particolari.

    Con OpenOffice Writer (non ho Word), se apri un file .txt compare una dialog che ti chiede come trattare il file nei confronti del charset (c'è una combobox con una sfilza di charset tra cui scegliere), del newline e altro.
Devi accedere o registrarti per scrivere nel forum
6 risposte