Domanda

Quindi ecco il problema: sto cercando di aprire un file (da byte), convertirlo in una stringa in modo da poter pasticciare con alcuni metadati nell'intestazione, riconvertirlo in byte e salvarlo. Il problema che sto incontrando in questo momento è con questo codice. Quando confronto la stringa che è stata convertita avanti e indietro (ma non altrimenti modificata) con l'array di byte originale, è ineguale. Come posso farlo funzionare?

public static byte[] StringToByteArray(string str)
{
    UTF8Encoding encoding = new UTF8Encoding();
    return encoding.GetBytes(str);
}

public string ByteArrayToString(byte[] input)
{
    UTF8Encoding enc = new UTF8Encoding();
    string str = enc.GetString(input);
    return str;
}

Ecco come li sto confrontando.

byte[] fileData = GetBinaryData(filesindir[0], Convert.ToInt32(fi.Length));
string fileDataString = ByteArrayToString(fileData);
byte[] recapturedBytes = StringToByteArray(fileDataString);
Response.Write((fileData == recapturedBytes));

Sono sicuro che sia UTF-8, usando:

StreamReader sr = new StreamReader(filesindir[0]);
Response.Write(sr.CurrentEncoding);

che restituisce " System.Text.UTF8Encoding " ;.

È stato utile?

Soluzione

Prova le funzioni statiche sulla classe Encoding che ti fornisce le istanze delle varie codifiche. Non è necessario creare un'istanza di == solo per convertire in / da un array di byte. Come stai confrontando le stringhe nel codice?

Modifica

Stai confrontando array, non stringhe. Sono disuguali perché si riferiscono a due matrici diverse; l'utilizzo dell'operatore <=> confronta solo i loro riferimenti, non i loro valori. È necessario ispezionare ciascun elemento dell'array per determinare se sono equivalenti.

public bool CompareByteArrays(byte[] lValue, byte[] rValue)
{
    if(lValue == rValue) return true; // referentially equal
    if(lValue == null || rValue == null) return false; // one is null, the other is not
    if(lValue.Length != rValue.Length) return false; // different lengths

    for(int i = 0; i < lValue.Length; i++)
    {
        if(lValue[i] != rValue[i]) return false;
    }

    return true;
}

Altri suggerimenti

Quando si hanno byte non elaborati (caratteri probabilmente non stampabili a 8 bit) e si desidera manipolarli come stringa .NET e trasformarli in byte, è possibile farlo utilizzando

Encoding.GetEncoding(1252)

invece di UTF8Encoding. Questa codifica funziona per prendere qualsiasi valore a 8 bit e convertirlo in un char .NET a 16 bit e viceversa, senza perdere alcuna informazione.

Nel caso specifico che descrivi sopra, con un file binario, non sarai in grado di " pasticciare con i metadati nell'intestazione " e far funzionare le cose correttamente a meno che la lunghezza dei dati con cui si scherza rimanga invariata. Ad esempio, se l'intestazione contiene

{any}{any}ABC{any}{any}

e vuoi cambiare ABC in DEF, che dovrebbe funzionare come desideri. Ma se vuoi cambiare ABC in WXYZ, dovrai scrivere sul byte che segue & Quot; C & Quot; o sposterai (in sostanza) tutto di un byte più a destra. In un tipico file binario, ciò rovinerà notevolmente le cose.

Se i byte dopo " ABC " sono spazi o caratteri null, c'è una migliore possibilità che scrivere dati di sostituzione più grandi non causi problemi - ma non puoi ancora sostituire ABC con WXYZ nella stringa .NET, allungandolo - dovresti sostituire ABC {whatever_follows_it} con WXYZ. Detto questo, potresti scoprire che è più semplice lasciare i dati come byte e scrivere i dati di sostituzione un byte alla volta.

A causa del fatto che le stringhe .NET usano stringhe Unicode, non puoi più farlo come facevano le persone in C. Nella maggior parte dei casi, non dovresti nemmeno tentare di andare avanti e indietro da string < ; - > byte array a meno che il contenuto non sia effettivamente testo .

Devo chiarire questo punto: in .NET, se i dati byte [] non sono testo , non tentare per convertirlo in una stringa ad eccezione della speciale codifica Base64 per dati binari su un canale di testo. Questo è un malinteso ampiamente diffuso tra le persone che lavorano in .NET.

Il tuo problema sembra essere il modo in cui stai confrontando l'array di byte:

Response.Write((fileData == recapturedBytes));

Questo restituirà sempre falso poiché stai confrontando l'indirizzo dell'array di byte, non i valori che contiene. Confronta i dati delle stringhe o usa un metodo per confrontare le matrici di byte. Puoi anche farlo invece:

Response.Write(Convert.ToBase64String(fileData) == Convert.ToBase64String(recapturedBytes));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top