Domanda

Sto consumando un feed di dati a cui è stata recentemente aggiunta un'intestazione BOM Unicode (U+FEFF) e il mio compito di rake ora ne è incasinato.

Posso saltare i primi 3 byte con file.gets[3..-1] ma esiste un modo più elegante per leggere i file in Ruby in grado di gestirlo correttamente, indipendentemente dal fatto che sia presente o meno una distinta base?

È stato utile?

Soluzione

Con Ruby 1.9.2 puoi utilizzare la modalità r:bom|utf-8

text_without_bom = nil #define the variable outside the block to keep the data
File.open('file.txt', "r:bom|utf-8"){|file|
  text_without_bom = file.read
}

O

text_without_bom = File.read('file.txt', encoding: 'bom|utf-8')

O

text_without_bom = File.read('file.txt', mode: 'r:bom|utf-8')

Non importa se la distinta base è disponibile nel file o meno.


Puoi anche utilizzare l'opzione di codifica con altri comandi:

text_without_bom = File.readlines(@filename, "r:utf-8")

(Ottieni un array con tutte le linee).

Oppure con CSV:

require 'csv'
CSV.open(@filename, 'r:bom|utf-8'){|csv|
  csv.each{ |row| p row }
}

Altri suggerimenti

Non saltato ciecamente i primi tre bytes; cosa succede se il produttore si ferma l'aggiunta di nuovo distinta base? Che cosa si dovrebbe fare è esaminare i primi byte, e se sono 0xEF 0xBB 0xBF, ignorarli. Questa è la forma il carattere BOM (U + FEFF) prende in UTF-8; Io preferisco trattare con esso prima di tentare di decodificare il flusso, perché la gestione della distinta base è così incoerente da una lingua / strumento / quadro a quella successiva.

In effetti, è così che sei dovrebbe per affrontare una distinta base. Se un file è stato servito come UTF-16, è necessario esaminare i primi due byte prima di iniziare la decodifica in modo da sapere se leggere come big-endian o little-endian. Naturalmente, l'UTF-8 BOM non ha nulla a che fare con l'ordine dei byte, è solo lì per farvi sapere che la codifica è UTF-8, nel caso non lo sa già che.

Mi piacerebbe non un file di "fiducia" per essere codificato come UTF-8 quando è presente una distinta di 0xEF 0xBB 0xBF, si potrebbe non riuscire. Di solito, quando il rilevamento del UTF-8 BOM, in realtà dovrebbe essere un file codificato UTF-8, naturalmente. Ma, se per esempio qualcuno ha appena aggiunto il BOM UTF-8 per un file ISO, che ci si riesce a codificare tale file così male se non ci sono byte in esso che sono al di sopra 0x0F. Ci si può fidare del file se si ha solo byte fino a 0x0F dentro, perché in questo caso si tratta di un file UTF-8 compatibile ASCII e allo stesso tempo si tratta di un file UTF-8 valido.

Se non ci sono solo i byte <= 0x0F all'interno del file (dopo il BOM), per essere sicuri che sia correttamente codifica UTF-8 si dovrà verificare la presenza di sequenze valide e - anche quando tutte le sequenze sono validi - assegno anche se ogni punto di codice da una sequenza utilizza la sequenza più breve possibile e controllare anche se non v'è alcun punto di codice che corrisponde a un alta o bassa surrogato. controllare anche se i byte massimo di una sequenza non è superiore a 4 e il codepoint massima è 0x10FFFF. I limiti massimi codepoint anche bit di payload del byte di start per essere non superiore a 0x4 e payload del primo byte successivo non superiore 0xF. Se tutti i controlli menzionati passano con successo, il tuo UTF-8 BOM dice la verità.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top