Un altro angolo di venire a questo da è che le classi Encoding
sono progettato per i dati di andata e ritorno, ma i dati sono progettati per andata e ritorno è char
dati, codificati a byte
, non il contrario .Ciò significa che, all'interno delle capacità dello Encoding
in questione, ciascun valore char
ha una codifica corrispondente nei valori byte
(1 o più) che torneranno esattamente nello stesso valore char
. (Vale la pena notare che non tutti i Encoding
s può fare questo per tutti possibili char
valori - per esempio, può solo sostenere char
valori nella gamma [0, 128)
.)
Quindi, se siete di partenza con il carattere dati e hai bisogno di un modo per archiviarli o inviarli in un supporto che funziona con byte (come un file su disco o un flusso di rete), Encoding
è un ottimo modo per convertire i dati char
in dati byte
e poi di nuovo sul altra fine. (Se si desidera supportare tutte le possibili stringhe, è necessario utilizzare uno dei Unicode-based Encoding
s, come ad esempio Encoding.Unicode
o Encoding.UTF8
.)
Allora, che cosa significa questo se si sta iniziando con un mucchio di byte
s? Bene, a seconda della codifica in questione, lo byte
s con cui stai lavorando potrebbe non essere effettivamente una sequenza che Encoding
avrebbe mai prodotto. Hai bisogno di guardare a Encoding.GetBytes
come operazione codifica, e Encoding.GetChars
/Encoding.GetString
come decodifica funzionamento, e così si sta iniziando con una serie arbitraria di byte e cercando di decodificarli.
Per un'analogia, prendere in considerazione il formato di file JPEG per le immagini. Questo ha un tipo simile di codifica e decodifica, dove in questo caso i dati decodificati non sono un string
ma un'immagine. Quindi, se prendi una stringa arbitraria di byte, quali sono le possibilità che possa essere decodificata come immagine JPEG? La risposta a questo, ovviamente, è molto sottile. Più probabilmente, i tuoi byte finiranno per scendere un percorso nel decodificatore che dice "Woah lì, non mi aspettavo quel byte per venire dopo quell'altro", e farà del suo meglio per gestire i dati sull'ipotesi che è un file JPEG valido che è stato danneggiato in qualche modo.
Esattamente la stessa cosa accade quando si converte una serie arbitraria di byte in una stringa. La codifica UTF-8 ha regole specifiche su come i codici char
128 vengono codificati, e una di queste regole dice che vedrai sempre un byte che corrisponde allo schema di bit 10xxxxxx
dopo uno che corrisponde a uno schema come 110xxxxx
, 1110xxxx
o 11110xxx
, che "introduce" una sequenza multi-byte (più byte
s che rappresenta un singolo char
). Quindi, se i tuoi dati contengono un byte corrispondente al modello che non corrisponde a seguendo uno degli "introduttori" previsti, l'encoder può solo presumere che i dati siano stati danneggiati in qualche modo. Che cosa fa? Inserisce un personaggio che dice: "Qualcosa è andato terribilmente storto con i dati codificati, ho fatto del mio meglio e qui è andato storto". Le persone che hanno progettato Unicode hanno anticipato questo scenario esatto e creato un personaggio con questo preciso significato: lo Replacement Character.
Quindi, se si sta cercando di andata e ritorno le vostre byte
s in una serie di char
s e si incontra questo scenario, il valore effettivo della incriminato byte
si perde, e invece viene inserito un carattere di rimpiazzo. Quando si prova a trasformare lo string
in un array byte
, finisce la codifica del Carattere sostitutivo, non i dati originali. I dati originali sono persi.
Quello che stai cercando è una codifica & relazione di decodifica che funziona nella direzione opposta. Encoding
consente di acquisire i dati char
e di trovare un modo per archiviarli temporaneamente come dati byte
. Se si desidera prendere i dati byte
e trovare un modo per archiviarli temporaneamente come dati char
, è necessaria una codifica progettata per tale scopo specifico. Fortunatamente, questi esistono. Wikipedia ha un fairly comprehensive list delle opzioni. :-)
All'interno di .NET Framework, l'opzione più semplice e più accessibile è la codifica MIME Base-64, che viene esposta tramite Convert.ToBase64String
e Convert.FromBase64String
.
La risposta che hai collegato a parla di ASCII, non di UTF-8. – svick
Puoi persino confrontare gli array di byte usando '=='? Questo probabilmente confronta solo i loro riferimenti, probabilmente dovrai fare un ciclo per confrontare ogni elemento dell'array per l'uguaglianza. – Matthew
@Matthew the gist of [that answer] (http://stackoverflow.com/a/3946274/85371) sembra essere che la codifica può variare. E sì, il codice di esempio è imperfetto/arretrato. – sehe