Pregunta

Entonces, este es el trato: estoy tratando de abrir un archivo (de bytes), convertirlo en una cadena para poder meter algunos metadatos en el encabezado, convertirlo nuevamente a bytes y guardarlo. El problema con el que me encuentro ahora es con este código. Cuando comparo la cadena que se ha convertido de un lado a otro (pero no se ha modificado) a la matriz de bytes original, es desigual. ¿Cómo puedo hacer que esto funcione?

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;
}

Así es como los estoy comparando.

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

Estoy seguro de que es UTF-8, usando:

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

que devuelve " System.Text.UTF8Encoding " ;.

¿Fue útil?

Solución

Pruebe las funciones estáticas en la clase Encoding que le proporciona instancias de las diferentes codificaciones. No debería necesitar crear una instancia de == solo para convertir a / desde una matriz de bytes. ¿Cómo estás comparando las cadenas en el código?

Editar

Estás comparando matrices, no cadenas. Son desiguales porque se refieren a dos matrices diferentes; usando el operador <=> solo comparará sus referencias, no sus valores. Deberá inspeccionar cada elemento de la matriz para determinar si son equivalentes.

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;
}

Otros consejos

Cuando tiene bytes sin procesar (caracteres de 8 bits posiblemente no imprimibles) y desea manipularlos como una cadena .NET y convertirlos nuevamente en bytes, puede hacerlo usando

Encoding.GetEncoding(1252)

en lugar de UTF8Encoding. Esa codificación funciona para tomar cualquier valor de 8 bits y convertirlo a un carácter .NET de 16 bits, y viceversa, sin perder ninguna información.

En el caso específico que describió anteriormente, con un archivo binario, no podrá " meterse con metadatos en el encabezado " y hacer que las cosas funcionen correctamente a menos que la longitud de los datos con los que te metas no cambie Por ejemplo, si el encabezado contiene

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

y desea cambiar ABC a DEF, eso debería funcionar como desee. Pero si desea cambiar ABC a WXYZ, tendrá que escribir sobre el byte que sigue & Quot; C & Quot; o (en esencia) moverá todo un byte más hacia la derecha. En un archivo binario típico, eso arruinará mucho las cosas.

Si los bytes después de " ABC " son espacios o caracteres nulos, hay una mejor posibilidad de que escribir datos de reemplazo más grandes no causará problemas, pero aún así no puede simplemente reemplazar ABC con WXYZ en la cadena .NET, lo que lo hace más largo, tendría que reemplazar ABC {whatever_follows_it} con WXYZ Dado eso, es posible que sea más fácil dejar los datos como bytes y escribir los datos de reemplazo un byte a la vez.

Debido al hecho de que las cadenas .NET usan cadenas Unicode, ya no puede hacer esto como lo hacían las personas en C. En la mayoría de los casos, ni siquiera debería intentar ir y venir de cadenas < ; - > conjunto de bytes a menos que el contenido sea en realidad texto .

Tengo que aclarar este punto: en .NET, si los datos de byte [] no son text , entonces no intente para convertirlo en una cadena excepto por la codificación especial Base64 para datos binarios sobre un canal de texto. Este es un malentendido generalizado entre las personas que trabajan en .NET.

Su problema parece ser la forma en que está comparando la matriz de bytes:

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

Esto siempre devolverá falso ya que está comparando la dirección de la matriz de bytes, no los valores que contiene. Compare los datos de la cadena o use un método para comparar las matrices de bytes. También podría hacer esto en su lugar:

Response.Write(Convert.ToBase64String(fileData) == Convert.ToBase64String(recapturedBytes));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top