variable tipo number from empty dato data array c# bytearray

number - tipo de dato byte c#



Eliminar nulos finales de la matriz de bytes en C# (10)

@Factor Mystic,

Creo que hay una manera más corta:

var data = new byte[] { 0x01, 0x02, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00 }; var new_data = data.TakeWhile((v, index) => data.Skip(index).Any(w => w != 0x00)).ToArray();

Ok, estoy leyendo en archivos dat en una matriz de bytes. Por alguna razón, las personas que generan estos archivos ponen alrededor de medio kilo de bytes nulos inútiles al final del archivo. ¿Alguien sabe una forma rápida de recortarlos del final?

Primero pensé en comenzar al final de la matriz e iterar hacia atrás hasta que encontrara algo más que un nulo, luego copiar todo hasta ese punto, pero me pregunto si no hay una mejor manera.

Para responder algunas preguntas: ¿Está seguro de que los 0 bytes están definitivamente en el archivo, en lugar de que haya un error en el código de lectura del archivo? Sí, estoy seguro de eso.

¿Puedes definitivamente recortar todos los 0 finales? Sí.

¿Puede haber 0 en el resto del archivo? Sí, puede haber otros 0 lugares, entonces, no, no puedo comenzar desde el principio y parar en el primer 0.


Asumiendo 0 = nulo, esa es probablemente su mejor opción ... como un ajuste menor, es posible que desee usar Buffer.BlockCopy cuando finalmente copie los datos útiles.


Dadas las preguntas adicionales ahora respondidas, parece que básicamente estás haciendo lo correcto. En particular, debe tocar cada byte del archivo desde el último 0 en adelante, para verificar que solo tenga 0.

Ahora, si tienes que copiar todo o no, depende de lo que estés haciendo con los datos.

  • Quizás puedas recordar el índice y guardarlo con los datos o el nombre del archivo.
  • Puede copiar los datos en una nueva matriz de bytes
  • Si desea "arreglar" el archivo, puede llamar a FileStream.SetLength para truncar el archivo

El "tienes que leer cada byte entre el punto de truncamiento y el final del archivo" es la parte crítica.


Estoy de acuerdo con Jon. El aspecto crítico es que debe "tocar" cada byte desde el último hasta el primer byte distinto de cero. Algo como esto:

byte[] foo; // populate foo int i = foo.Length - 1; while(foo[i] == 0) --i; // now foo[i] is the last non-zero byte byte[] bar = new byte[i+1]; Array.Copy(foo, bar, i+1);

Estoy bastante seguro de que es casi tan eficiente como de poder lograrlo.


Puede contar el número de cero al final de la matriz y usarlo en lugar de .Length al iterar la matriz más adelante. Puedes encapsular esto como quieras. El punto principal es que realmente no necesita copiarlo en una nueva estructura. Si son grandes, puede valer la pena.


Qué tal esto:

[Test] public void Test() { var chars = new [] {''a'', ''b'', ''/0'', ''c'', ''/0'', ''/0''}; File.WriteAllBytes("test.dat", Encoding.ASCII.GetBytes(chars)); var content = File.ReadAllText("test.dat"); Assert.AreEqual(6, content.Length); // includes the null bytes at the end content = content.Trim(''/0''); Assert.AreEqual(4, content.Length); // no more null bytes at the end // but still has the one in the middle }


Siempre hay una respuesta LINQ

byte[] data = new byte[] { 0x01, 0x02, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00 }; bool data_found = false; byte[] new_data = data.Reverse().SkipWhile(point => { if (data_found) return false; if (point == 0x00) return true; else { data_found = true; return false; } }).Reverse().ToArray();


si en el archivo, los bytes nulos pueden ser valores válidos, ¿sabe usted que el último byte en el archivo no puede ser nulo? si es así, es mejor repetir hacia atrás y buscar la primera entrada no nula; de lo contrario, no hay forma de saber dónde está el final real del archivo.

Si sabe más sobre el formato de datos, como que no puede haber una secuencia de bytes nulos de más de dos bytes (o alguna restricción similar). Entonces es posible que pueda hacer una búsqueda binaria para el "punto de transición". Esto debería ser mucho más rápido que la búsqueda lineal (suponiendo que pueda leer todo el archivo).

La idea básica (usando mi suposición anterior sobre no bytes nulos consecutivos) sería:

var data = (byte array of file data...); var index = data.length / 2; var jmpsize = data.length/2; while(true) { jmpsize /= 2;//integer division if( jmpsize == 0) break; byte b1 = data[index]; byte b2 = data[index + 1]; if(b1 == 0 && b2 == 0) //too close to the end, go left index -=jmpsize; else index += jmpsize; } if(index == data.length - 1) return data.length; byte b1 = data[index]; byte b2 = data[index + 1]; if(b2 == 0) { if(b1 == 0) return index; else return index + 1; } else return index + 2;


prueba esto:

private byte[] trimByte(byte[] input) { if (input.Length > 1) { int byteCounter = input.Length - 1; while (input[byteCounter] == 0x00) { byteCounter--; } byte[] rv = new byte[(byteCounter + 1)]; for (int byteCounter1 = 0; byteCounter1 < (byteCounter + 1); byteCounter1++) { rv[byteCounter1] = input[byteCounter1]; } return rv; }


En mi caso, el enfoque de LINQ nunca terminó ^))) ¡Es lento para trabajar con matrices de bytes!

Chicos, ¿por qué no usarán el método Array.Copy ()?

/// <summary> /// Gets array of bytes from memory stream. /// </summary> /// <param name="stream">Memory stream.</param> public static byte[] GetAllBytes(this MemoryStream stream) { byte[] result = new byte[stream.Length]; Array.Copy(stream.GetBuffer(), result, stream.Length); return result; }