Discusión sobre el artículo "Trabajamos con archivos ZIP con los medios de MQL5, sin usar bibliotecas ajenas" - página 9

 
Forester #:
Descargado y descomprimido casi 300 archivos. Y los datos que contienen son cada vez mayores y han alcanzado el límite de tamaño.
El archivo debería tener 1.800 millones de elementos char, pero se descomprime cortado a 1.500 millones. Se pierden algunos datos. Es extraño que esté cortado tan corto, los arrays pueden tener hasta 2147483647 elementos.

He clasificado los ficheros (desempaquetados) que superan un cierto volumen (para diferentes ficheros desde 1,7GB hasta 2136507776 - es decir, casi hasta MAX_INT=2147483647, y los arrays no pueden tener más elementos) y que se cortan a la salida. Resulta que todos ellos están marcados como erróneos en:

CryptDecode(CRYPT_ARCH_ZIP, m_file_puck, key, file_array);

Es decir, valor de salida = 0.
Pero CZIP no controla esto. Hice la puesta a cero del tamaño del array de salida.
Así en mis funciones puedo determinar con 100% de garantía que el archivo se descomprimió exitosamente.
Antes comprobaba el final correcto del archivo JSON }\r\n - pero esta solución no es universal y parece que varios archivos de ~1000 fueron cortados accidentalmente por una línea intermedia y fueron aceptados como descomprimidos con éxito, pero los datos en ellos no están completos.

Nueva versión de la función:

void CZipFile::GetUnpackFile(uchar &file_array[])
{
   static const uchar key[] = {1, 0, 0, 0};
   if(m_header.comp_method)
   {
      int dSize=CryptDecode(CRYPT_ARCH_ZIP, m_file_puck, key, file_array);
      if(dSize==0){Print("Err in CriptDecode. Arr size: ",ArraySize(file_array));ArrayResize(file_array,0);}//restablecer el tamaño a 0
   }
   else
   {
      ArrayCopy(file_array, m_file_puck);
   }
}

La nueva está resaltada enamarillo .

Quizás los desarrolladores también deberían poner a cero el array, porque los datos recortados casi nadie los necesita. Y puede dar lugar a errores difíciles de ver.

 
Forester #:

He ordenado los ficheros (descomprimidos) que superan un determinado volumen (para diferentes ficheros desde 1,7Gb hasta 2136507776 - es decir, casi hasta MAX_INT=2147483647, y los arrays no pueden tener más elementos) y que se cortan a la salida. Resultó que todos ellos fueron marcados como erróneos en:

Es decir, valor de salida = 0.
Pero CZIP no controla esto. Hice la puesta a cero del tamaño de la matriz de salida.
Así en mis funciones puedo determinar con 100% de garantía que el archivo es desempaquetado con éxito.
Antes comprobaba el final correcto del archivo JSON }\r\n - pero esta solución no es universal y parece que varios archivos de ~1000 fueron cortados accidentalmente por una línea intermedia y fueron aceptados como descomprimidos con éxito, pero los datos en ellos no están completos.

Nueva versión de la función:

La nueva está resaltadaen amarillo .

Quizás los desarrolladores también deberían poner a cero el array, porque los datos recortados casi nadie los necesita. Y puede dar lugar a errores difíciles de ver.

En primer lugar, el valor de retorno 0 no es una señal de error al 100% (esto es probablemente un remanente de los tiempos en que la función se usaba sólo para encriptar, pero no para comprimir - probablemente debería cambiarse, pero es poco probable que lo hagan, para no dañar la compatibilidad hacia atrás) para descomprimir zip, porque zip puramente permite técnicamente archivar datos vacíos ("receiver array" estará vacío legítimamente, sin ningún error).

En segundo lugar, la presencia de datos parcialmente descomprimidos puede ser útil para el diagnóstico de errores, por lo que es mejor dejarlos.

 
Stanislav Korotky #:

En primer lugar, un valor de retorno de 0 no es 100% indicativo de un error

Con mis ~1000 archivos, la etiqueta con 0 - me permitió descartar todos los archivos que busqué por el patrón de fin de archivo (es decir, funcionó al 100%) y otros 5 que aparentemente estaban cortados por el final de la línea.
Así que es más fiable que mi método.

En segundo lugar, la presencia de datos parcialmente desempaquetados puede ser útil para diagnosticar errores, por lo que es mejor dejarlos.

En mi caso quedan unos 5 archivos cortados, que terminaron de la misma forma que el final esperado del archivo y que no se pueden comprobar de ninguna otra forma - es decir, no se trata de diagnóstico de errores, sino de omisión de errores en el algoritmo de trabajo.
¿Tus opciones de diagnóstico de errores?

Sin embargo, he resuelto la cuestión por mí mismo. Pero los errores se saltaban hasta que he descifrado el código de otra persona. Si hubiera puesta a cero en el lado MT, no estarían allí.

En general, hay argumentos a favor y en contra. Los desarrolladores decidirán qué es mejor/lógico.

PS. Usted puede agregar -1 para el error de zip con 0 archivo de longitud.
 
Forester #:

En mi caso, hay unos 5 archivos recortados que terminaron igual que el final esperado del archivo y ya no se pueden comprobar de ninguna manera, es decir, no se trata de un diagnóstico de errores, sino de una omisión de errores en el algoritmo de trabajo.

¿Cuáles son sus opciones para el diagnóstico de errores?

Sin embargo, he resuelto la cuestión por mí mismo. Pero los errores se omitieron hasta que resolví el código de otra persona. Si hubiera un reinicio en el lado MT, no estarían allí.

No entendía cómo se podían saltar los errores. La función devuelta no cero y una matriz llena con datos parcialmente faltantes del archivo? Entonces esto es un error en MQL5 - debe ser corregido allí.

¿Se ha comprobado la bandera _LastError?

El "final esperado del archivo" nunca debe ser establecido, porque el archivo es una cosa generalizada - podemos no saber el formato del archivo recibido.

 
Stanislav Korotky #:

No me había dado cuenta de los errores que se podían haber pasado por alto.

Se trata de un fallo en la librería CZIP del artículo. No se comprobaba el resultado del desempaquetado. Era sólo

CryptDecode(CRYPT_ARCH_ZIP, m_file_puck, key, file_array);

Justo hoy he encontrado esto y he añadido esta comprobación ver resaltada en amarillo.

int dSize=CryptDecode(CRYPT_ARCH_ZIP, m_file_puck, key, file_array);
if(dSize==0){Print("Err in CriptDecode. Arr size: ",ArraySize(file_array));ArrayResize(file_array,0);}//restablecer el tamaño a 0

Al principio de usarlo, no me di cuenta de que no había comprobación - por eso inventé mi comprobación para el final esperado del archivo.

Nunca se debe confiar en "fin de archivo esperado" porque el archivado es algo generalizado - podemos no conocer el formato del archivo recibido.

Estoy de acuerdo, por eso hice la puesta a cero del array en caso de error.
Esto es lo más universal que se puede hacer, excepto para el caso con 0 tamaño de archivo.
Pero incluso con 0-th tamaño del archivo no voy a procesar / analizar JSON y nadie lo hará - sólo bucles en los elementos no se iniciará si el número de elementos = 0, por lo que la puesta a cero de la matriz, en mi opinión, es una buena solución.

 
Adjunto una pequeña modificación del código de la librería para las nuevas realidades (b5223+) de MQL5.
Новая версия платформы MetaTrader 5 build 5200: расширение OpenBLAS и усиление контроля в MQL5
Новая версия платформы MetaTrader 5 build 5200: расширение OpenBLAS и усиление контроля в MQL5
  • 2025.08.20
  • www.mql5.com
В пятницу 1 августа 2025 года будет выпущена обновленная версия платформы MetaTrader 5...
Archivos adjuntos:
ZipHeader.mqh  27 kb
 
Forester #:

Me encontré con un archivo que CZip no podía descomprimir. Al mismo tiempo 7ZIP y el archivador de Windows descomprimen sin problemas.
Imprimí el tamaño de los datos comprimidos - resultó ser decenas de megabytes menos que el archivo (y sólo hay 1 archivo en él).

Empecé a buscar dónde se calcula, y lo encontré en la función FindZipFileSize().

Experimenté...
Resultó que si devuelves todos los datos de end_size como tamaño de los datos, el archivo se desempaqueta correctamente. Aparentemente, al desempaquetar, el propio código determina el final de los datos, en lugar de confiar en la respuesta de esta función. Se podría dejar así, pero resulta que la función es inútil, lo cual es poco probable. Y quizás algún otro archivo falle...
Un experimento más demostró que si comentas las líneas

El archivo también empieza a descomprimirse. La cantidad de datos se acerca al 100%.

Resulta que el archivo tiene uint cdheader = 0x504b0102; y esto es una parte de los datos comprimidos, no una etiqueta de su final.

¿Se ha equivocado con la etiqueta? Encontré tal etiqueta en la búsqueda de Internet. Tal vez debería ser procesado de alguna otra manera, en lugar de cortar los datos por ella, corté 30MB.

Función de trabajo con este archivo: (archivo \Include\Zip\Zip.mqh).

Puedo enviarte el archivo comprimido en un mensaje privado, si te interesa averiguarlo.

La cosa es que hay un formato Zip, que esta precisamente regulado y descrito, y hay varios empaquetadores (windows, total commander, 7zip, etc.), que se atornillan en este estandar y cada uno es muy creativo en llenar estructuras de encabezado. Así que CZip no puede confiar en que el formato se rellene correctamente, y calcula lo que puede por su cuenta. Lo que hay con el identificador 0x504b0102 debe ser resuelto.

Deberíamos revisar el código de nuevo y lanzar una actualización que tenga en cuenta sus valiosos comentarios. Me alegro de que alguien esté usando la lib.

 
fxsaber #:
Adjunto una pequeña modificación del código de la librería para las nuevas realidades (b5223+) de MQL5.

Gracias. MQL5 es cada vez más insensato y despiadado.

El 99% de los errores se podrían haber evitado si MetaQuotes hubiera implementado de una vez las funciones estándar de reflexión y serialización.

 
Forester #:

Me encontré con un archivo que CZip no pudo descomprimir. Sin embargo, 7ZIP y el archivador de Windows lo descomprimieron sin problemas.

...

Puedo enviarte el archivo en un mensaje privado si estás interesado en resolverlo.

Por favor, envíeme el archivo en un mensaje privado.

 
Vasiliy Sokolov #:

Por favor, envíeme el archivo en un mensaje privado.

https://quote-saver.bycsi.com/orderbook/linear/BTCUSDT/2023-01-18_BTCUSDT_ob500.data.zip

aquí en el cuerpo del archivo (no en la cabecera) hay cdheader = 0x504b0102;

En el archivo siguiente por fecha también. Creo que se encuentra a menudo.

header = 0x504b0304; está en cada archivo en el encabezado, es decir, los primeros 4 caracteres.
Pero también se reunió y en el cuerpo del archivo, rara vez. Voy a buscar ahora.

Aquí https://quote-saver.bycsi.com/orderbook/linear/BTCUSDT/2023-03-15_BTCUSDT_ob500.data.zip.


Creo que es necesario buscar estas cabeceras sólo entre los cuerpos de archivos.