¿Cómo podría eliminar una cantidad de bytes de una matriz de bytes?¿Quitar los primeros 16 bytes?
Respuesta
EDIT: Como comentario de nobugz (y la respuesta de Reed Copsey) menciona, si no necesita realmente el resultado como una matriz de bytes, usted debe buscar en el uso de ArraySegment<T>
:
ArraySegment<byte> segment = new ArraySegment<byte>(full, 16, full.Length - 16);
De lo contrario, la copia será Es necesario: las matrices siempre tienen un tamaño fijo, por lo que no puede "eliminar" los primeros 16 bytes de la matriz existente. En su lugar, deberá crear una nueva matriz más pequeña y copiar los datos relevantes en ella.
sugerencia de Zach es en la dirección correcta para el enfoque no LINQ, pero puede ser más sencilla (se asume que ya conoce la matriz original es de al menos 16 bytes de longitud):
byte[] newArray = new byte[oldArray.Length - 16];
Buffer.BlockCopy(oldArray, 16, newArray, 0, newArray.Length);
o
byte[] newArray = new byte[oldArray.Length - 16];
Array.Copy(oldArray, 16, newArray, 0, newArray.Length);
I sospechosoBuffer.BlockCopy
habrá un poco más rápido, pero no lo sé a ciencia cierta.
Tenga en cuenta que ambos éstos podrían ser significativamente más eficaz que el enfoque LINQ si las matrices involucradas son grandes: el enfoque LINQ requiere cada byte a devolver individualmente de un iterador, y copias potencialmente intermedios que se hizo (en la misma forma en que agregar elementos a un List<T>
necesita hacer crecer periódicamente el conjunto de respaldo). Obviamente no micro-optimize, pero vale comprobando si este bit de código es un cuello de botella de rendimiento.
EDIT: ejecuté un punto de referencia muy "rápido y sucio" de los tres enfoques. No confío en que el punto de referencia distinga entre Buffer.BlockCopy
y Array.Copy
- estuvieron muy cerca - pero el enfoque LINQ fue más de 100 veces más lento.
En mi computadora portátil, usando matrices de bytes de 10.000 elementos, me llevó casi 10 segundos realizar 40,000 copias con LINQ; los enfoques anteriores tomaron cerca de 80ms para hacer la misma cantidad de trabajo. Aumenté el recuento de iteraciones a 4.000.000 y solo tardó unos 7 segundos. Obviamente, se aplican las advertencias normales sobre los micro-puntos de referencia, pero esta es una diferencia bastante significativa.
Definitivamente el uso del enfoque anterior, si este se encuentra en una ruta de código que es importante para el rendimiento :)
+1, el almacenamiento en búfer es definitivamente más eficiente para matrices grandes. –
¿Cuál es la diferencia entre Buffer.BlockCopy y Array.Copy cuando se usa con matrices de bytes? – dtb
@dtb: no espero que exista ninguna diferencia funcional en este caso. 'Buffer.BlockCopy' es un poco más restrictivo. Sospecho que se implementó en un nivel inferior, pero no conozco los detalles. –
Usted puede hacer esto:
using System.Linq
// ...
var newArray = oldArray.Skip(numBytes).ToArray();
Si no puede utilizar LINQ, que podría hacerlo de esta manera:
byte[] myArray = // however you acquire the array
byte[] newArray = new byte[myArray.Length - 16];
for (int i = 0; i < newArray.Length; i++)
{
newArray[i] = myArray[i + 16];
}
// newArray is now myArray minus the first 16 bytes
También tendrá que manejar el caso en el que la matriz tiene menos de 16 bytes de longitud.
voy a mencionar también - dependiendo de cómo se va a utilizar los resultados, a menudo, un enfoque alternativo es utilizar ArraySegment<T>
para acceder a la porción restante de la matriz. Esto evita la necesidad de copiar la matriz, que puede ser más eficiente en algunos escenarios de uso:
ArraySegment<byte> segment = new ArraySegment<byte>(originalArray, 16, originalArray.Length-16);
// Use segment how you'd use your array...
- 1. Eliminando los primeros 16 bytes de una matriz de bytes
- 2. Descargar los primeros 1000 bytes
- 3. Metaetiqueta no en los primeros 1024 bytes
- 4. CipherInputStream solo lee 16 bytes (AES/Java)
- 5. Encriptación AES de 16 bytes sin sal
- 6. fread Sólo los primeros 5 bytes del archivo .PNG
- 7. ¿Cómo puedo ver los primeros dos bytes en un InputStream?
- 8. Comprimir 21 caracteres alfanuméricos en 16 bytes
- 9. Java: quitar segmento Continious de ceros del conjunto de bytes
- 10. Lectura atómica de 16 bytes en CPU x64
- 11. Cómo comparar primeros N bytes de archivos binarios en Linux
- 12. ¿Cómo puedo quitar los primeros X caracteres de la cadena usando sed?
- 13. Convertir 16 bits con la firma int a 2 bytes?
- 14. cómo convertir dos bytes en un número de 16 bits?
- 15. ¿Por qué es mejor struct con menos de 16 bytes?
- 16. Cómo asignar datos de memoria de 16 bytes
- 17. ¿Cómo puedo decodificar datos UTF-16 en Perl cuando no conozco el orden de bytes?
- 18. ¿Cuál es el mejor método para obtener Int32 de los primeros cuatro bytes de GUID?
- 19. Eliminar los primeros bytes de un archivo de acceso aleatorio en Java
- 20. Cómo obtener solo los primeros diez bytes de un archivo binario
- 21. ¿Quitar los soportes en json?
- 22. SerializeJSON solo devolviendo los primeros dos registros
- 23. MySQL omita los primeros 10 resultados
- 24. ¿Cómo obtener los primeros X elementos?
- 25. Obtenga los primeros 100 elementos de OrderedDict
- 26. Devolviendo los primeros N caracteres de una cadena Unicode
- 27. C# - Lista - eliminar todos los elementos pero NO los primeros
- 28. XPath - Todos los hermanos siguientes excepto los primeros elementos específicos
- 29. Lea lo que necesite, ¿cómo leer los primeros 256 bytes del archivo grande en línea sin descargar?
- 30. Como IPV6 necesita 128 bits (16 bytes), ¿por qué en postgres el tipo de datos CIDR tiene un almacenamiento de 24 bytes (8.1) y 19 bytes (9.1)?
Otra pregunta SO defectuosa, hemos estado recibiendo muchas de ellas últimamente. Distinguido por una pregunta de una sola oración que no hace mucho para explicar el título. Con mucho, el mejor enfoque es no hacerlo.Muchos métodos que toman una matriz tienen una sobrecarga que toma una compensación y longitud. Incluso hay una clase dedicada para él: ArraySegment. Ya sea que eso te ayude no está claro a partir de tu pregunta. Probablemente no. –