Trabajar con archivos. - página 4

 

TheXpert:

¡OMG! Donde está la salida, está el sinsentido. Así es como se producen afirmaciones como "la POO es más rápida" o "los indicadores son lentos, deberíamos poner todo el código en el Asesor Experto".

Entiendo que no todo funciona como estaba previsto. Al menos, el uso normal de FileFlush() debería ser más rápido que FileClose().

Pero sigo pensando que esas cosas no deben ponerse en los bucles; de todas formas no serán de mucha ayuda.

Y si entendí bien el ejemplo para MQL4, la llamada de FileFlush() se coloca entre dos bucles (me sugirió que sería un freno en un bucle).

  int bars_count=Bars;
  int handle=FileOpen("mydat.csv",FILE_CSV|FILE_WRITE);
  if(handle>0)
    {
     FileWrite(handle, "#","OPEN","CLOSE","HIGH","LOW");
     for(int i=0;i<bars_count;i++)
       FileWrite(handle, i+1,Open[i],Close[i],High[i], Low[i]);
     

FileFlush(handle);

     ...      for(int i=0;i<bars_count;i++)        FileWrite(handle, i+1,Open[i],Close[i],High[i], Low[i]);      FileClose(handle);     }

Por lo tanto, si entiendo correctamente la lógica de los desarrolladores, el archivo debe ser abierto en OnInit / Constructor de la clase principal (tal vez no sólo en el constructor) y cerrado en OnDeint / Destructivo de la clase principal.

Entodos los demás casos, en lugar de FileClose utilice FileFlush (después de FileWrite y después de los bucles).


 

TheXpert:

Yedelkin:

He intercambiado las líneas según la documentación:

         FileFlush(handle_file);
         FileWrite(handle_file,t);

¿Dónde está escrito esto en la documentación?

Hay una frase de este tipo en MQL5 Reference:

FileFlush

Nota

La función FileFlush() debe ser llamada entre las operaciones de lectura de un archivo y de escritura en un archivo.

Si "escribir en el archivo" == función FileWrite(), entonces leer: "La función FileFlush() debe serllamada antes de la función FileWrite()". ¿O tiene una opinión diferente?

TheXpert:

Yedelkin:
Pero sigo sin entender el sentido de llamar a FileFlush() antes de FileWrite().

¿Cómo se puede dar sentido a algo que no lo tiene? Vuelva a colocar el orden de las líneas en la página de inicio y vuelva a comprobarlo. Por lo visto, la documentación no lo ponía bien.

Es bueno saber de antemano lo que tiene sentido y lo que no cuando se estudia un nuevo material. Como la naturaleza no nos ha dotado de tales talentos, tenemos que "tomar cada nueva altura", probar, interpretar la documentación y los resultados. Ni siquiera estoy seguro de que las propias pruebas estén escritas correctamente. Al principio puse intuitivamente FileFlush() después de FileWrite(), pero después de releer el Manual borré ese ejemplo.

TheXpert:

Interesante:

¡OMG! Es absurdo donde está la salida. Así es como se producen afirmaciones como "OOP es más rápido" o "los indicadores son lentos, deberíamos poner todo el código en Expert Advisor".

Estaría bien que cada evaluación de "tu salida es estúpida" fuera seguida de la explicación de qué es lo que es estúpido en ella :) Por lo demás, no está claro en qué dirección moverse inquisitorialmente con tanto rigor del poder judicial :)

 
TheXpert:

No tiene sentido hacer desaparecer los cambios antes de que aparezcan, ya que aún no están ahí :)

No te lo vas a creer, pero precisamente por eso escribí "Pero no entiendo el sentido de llamar a FileFlush() antes de FileWrite()", refiriéndome a la documentación anterior. Pero no tengo el suficiente valor y conocimiento para cuestionar cada línea de la documentación :)
... Bueno, el curso está claro - estamos esperando lo que los desarrolladores dirán si realmente se detecta algún problema.
 
Yedelkin:

Hay una frase de este tipo en MQL5 Reference:

Si "write to file" == función FileWrite(), se lee: "La función FileFlush() debe ser llamada antes de la función FileWrite() ".¿O tiene una opinión diferente?

Analicemos la descripción "bastante desafortunada" y el ejemplo de esta función para MQL4.

void FileFlush( int mango)


Restablece en el disco todos los datos que quedan en el buffer de E/S del archivo.

Nota: La función FileFlush() debe ser llamada entre las operaciones de lectura y escritura de archivos.
Cuando se cierra el archivo, los datos se vuelcan automáticamente al disco, por lo que no es necesario llamar a FileFlush() antes de llamar a FileClose().

La línea marcada aquí es el argumento de la necesidad de llamar a FileFlush en el bucle antes de escribir en el archivo.

Pero si entendemos este comentario palabra por palabra obtendremos lo siguiente:

la función FileFlush() debe ser llamada entre las operaciones de lectura del archivo (mientras que la lectura es FileReadXXX) y la escritura en el archivo (la escritura está relacionada con FileWrite y FileWriteXXX).

Al cerrar el archivo (leer - cuando se ejecuta FileClose), los datos se vuelcan al disco automáticamente (leer - cuando se ejecuta FileFlush automáticamente).


Creo que los desarrolladores no se preocuparon mucho por la corrección de la lectura de la ayuda incluso en la versión MQL4; es incluso ridículo hablar de poner la parte truncada en MQL5.

En mi opinión, al menos la segunda frase del comentario anterior debería quedar así:

Los datos se restablecen automáticamente en el disco cuando secierra el archivo, por lo que no es necesario llamar a FileFlush() antes de llamar a FileClose().

Es un poco desordenado también, pero desde cierto punto de vista explica por qué no se debe usar FileFlush antes de cerrar el archivo usando FileClose.


El ejemplo no es tan simple, el texto dice sobre una cosa (uso entre operaciones de lectura y escritura), mientras que el ejemplo describe el uso entre dos operaciones de escritura de bucles (el trabajo dentro de los bucles, por cierto, no se considera en la ayuda en absoluto).

Por lo tanto, como mínimo, debería añadirse lo siguiente:

1. una descripción de lo que es este búfer de entrada/salida y lo que realmente ocurre en él entre la apertura de un archivo, la lectura de un bloque de datos, la escritura de un bloque de datos y el cierre del archivo.

Lo más probable es que se refiera a toda la sección de operaciones de archivo.

2. Dé un ejemplo que se entienda normalmente (puede estar basado en una clase) de cómo utilizar correctamente la llamada FileFlush para el acceso a un solo archivo (por ejemplo, escribir el valor del temporizador).

3 Proporcionar un ejemplo normal de una llamada cuando se trabaja con arrays. Por lo que entiendo, el ejemplo descrito en la Referencia MQL4 se refiere a trabajar con arrays grandes, pero lo ilustra incorrectamente (en una palabra - ¿por qué escribir dos veces una cantidad bastante grande de datos idénticos en el archivo, si se puede hacer varias veces?)

FileFlush - Документация на MQL4
  • docs.mql4.com
FileFlush - Документация на MQL4
 
Interesting:

La línea resaltada aquí es su argumento para la necesidad de llamar a FileFlush en el bucle antes de escribir en el archivo.

Pero si entendemos este comentario palabra por palabra obtenemos lo siguiente:

la función FileFlush( ) debe ser llamada entre las operaciones de lectura del archivo (mientras que la lectura es FileReadXXX) y la escritura en el archivo (la escritura está relacionada con FileWrite y FileWriteXXX).

Al cerrar el archivo (leer - cuando se ejecuta FileClose) los datos se vaciarán automáticamente en el disco (leer - cuando se ejecuta FileFlush).

Entiendo lo que quieres decir. Lo siento, que sin saberlo he equiparado la operación "leer del archivo" a la función FileOpen() (mi Asesor Experto leerá sólo desde OnInit(), mientras que durante el procesamiento de ticks y eventos personalizados - sólo escribir; por esta razón no he considerado funciones como FileReadXXX() en el bucle). Sin embargo, FileFlush() antes de FileWriteXXX() - el principio es el mismo en ambas referencias. Y no era una argumentación en su sentido clásico (como razonamiento de mi posición), sino simplemente una respuesta a la pregunta de por qué hice esa frase.

De todos modos, si los desarrolladores no responden aquí, publicaré una solicitud esta noche, con un enlace a la discusión y los resultados intermedios. Incluso se necesitan dos aplicaciones: 1) "error - no es un error" y 2) cambios en la documentación. ¿Le gustaría hacer la segunda solicitud usted mismo, ya que ha profundizado tanto en el tema?

 
Yedelkin:

Veo lo que estoy pensando. Confieso que, sin saberlo, he equiparado la operación "leer del archivo" a la función FileOpen() (mi Asesor Experto leerá sólo desde OnInit(), mientras que durante el procesamiento de los ticks y los eventos del usuario - sólo escribirá; por esta razón no he considerado funciones como FileReadXXX() en el bucle). Sin embargo, FileFlush() antes de FileWriteXXX() - el principio es el mismo en ambas referencias. Y no era una argumentación en su sentido clásico (como razonamiento de mi posición), sino simplemente una respuesta a la pregunta de por qué hice esa frase.

De todos modos, si los desarrolladores no responden aquí, publicaré una solicitud esta noche, con un enlace a la discusión y los resultados intermedios. Incluso se necesitan dos aplicaciones: 1) "error - no es un error" y 2) cambios en la documentación. ¿Le gustaría escribir la segunda solicitud usted mismo, ya que ha profundizado tanto en el tema?

1. ¿Es tan profundo? Probablemente estaría encantado de hacerlo, si entendiera lo que los desarrolladores quieren decir y dónde.

A veces se menciona un búfer de E/S pero no se describe adecuadamente. ¿O es que todo el mundo sabe lo que es el buffer de E/S de FILE?

¿Es difícil añadir una descripción normal de esta cuestión en el capítulo de operaciones de archivo? ¿O buscar por todo el mundo una respuesta a lo que los desarrolladores tenían en mente?

Entiendo que el tamaño de la ayuda es limitado, pero ¿por qué deberíamos burlarnos de los que están empezando a aprender MQL?

2. ¿Por qué se menciona este búfer que sólo he encontrado en la ayuda de esta función, por qué no se menciona en otra parte en la sección de operaciones con archivos?

3. Supongamos que tengo una idea de este mismo buffer de entrada/salida aproximadamente de esta forma

La noción de búfer de entrada-salida está relacionada con el sistema de archivos. Los datos de entrada y salida se realizan a través de este buffer.

El bufferes un área de la memoria que se asigna a cada archivo.

Al registrar en un archivo toda la información al principio se dirige al buffer y allí se acumula hasta que todo el volumen del buffer no se llene. Sólo después de eso o después de un comando especial de volcado (por ejemplo, FileClose o FileFlush). los datos se transfieren del buffer al archivo.

Cuando se lee de un archivo, los datos se leen primero en el búfer, y no se leen tantos datos como se solicitan, sino tantos como caben en el búfer.

¿Y los desarrolladores creen realmente que toda esta información puede ser interesante para un recién llegado que estudie MQL (si sólo esta definición puede considerarse válida para este lenguaje)?

Por ejemplo, me preguntaba cuál es el tamaño de este búfer y cómo se define.

En mi opinión, toda esta información, y no sólo ésta, debería estar en la documentación del idioma (allí, y no en diversos artículos y discusiones en el foro).

 
Interesting:
Bien, intentaré escribir una referencia yo mismo
 

¿Por qué el script no devuelve la"Fecha de última lectura" real del archivo?

int handle_file;
void OnStart()
  {
   handle_file=FileOpen("Ye_file2.bin",FILE_READ|FILE_WRITE|FILE_BIN);
   switch(handle_file)
     {
      case  INVALID_HANDLE: break;
      default:
         Print("Дата создания файла Ye_file2.bin: ",(datetime)FileGetInteger(handle_file,FILE_CREATE_DATE));
         for(int i=0;i<3;i++)
           {
            Sleep(3000);
            FileReadInteger(handle_file,CHAR_VALUE);
            Print("Дата последнего чтения Ye_file2.bin: ",(datetime)FileGetInteger(handle_file,FILE_ACCESS_DATE));
           }
         FileClose(handle_file);
     }
  }
 
Yedelkin:

¿Por qué el script no devuelve la"Fecha de última lectura" real del archivo?

Último acceso, no lectura. Vuelve a abrir el mango y serás feliz.
 
TheXpert:
Último acceso, no acceso de lectura.

Vale, como habrás notado, en mi pregunta he citado la frase textualmente de la documentación:

ENUM_FILE_PROPERTY_INTEGER

Identificador

Descripción del identificador

FILE_EXISTS

Comprobación de existencia

FECHA_DE_CREACIÓN_DEL_ARCHIVO

Fecha de creación

FILE_MODIFY_DATE

Última fecha de modificación

FECHA_DE_ACCESO_AL_ARCHIVO

Fecha de la última lectura

Pregunta 1: ¿Cree que hay un error tipográfico en la documentación, y que en lugar de "Última fecha de lectura" debería ser algo así como "Última fecha de apertura"? Al menos por tu respuesta, puedes ver que las operaciones de "leer archivo" y "acceder a archivo" significan cosas diferentes para ti.

Además. Si reinicia el script adjunto varias veces, verá aproximadamente el mismo comportamiento:

FK      0       FileInteger (EURGBP,M1) 21:33:56        Дата создания файла Ye_file2.bin: 2011.09.03 21:22:25
IP      0       FileInteger (EURGBP,M1) 21:33:59        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:33:57
RL      0       FileInteger (EURGBP,M1) 21:34:02        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:33:57
NH      0       FileInteger (EURGBP,M1) 21:34:06        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:33:57
MH      0       FileInteger (EURGBP,M1) 21:34:43        Дата создания файла Ye_file2.bin: 2011.09.03 21:22:25
EP      0       FileInteger (EURGBP,M1) 21:34:46        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:34:06
 HL      0       FileInteger (EURGBP,M1) 21:34:50        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:34:06
IH      0       FileInteger (EURGBP,M1) 21:34:53        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:34:06

Es decir, al ejecutar el script por primera vez, la tercera llamada aFileReadInteger() tiene lugar a las21:34:06, pero la fecha de la última lectura/acceso es diferente:21:33:57.Sin embargo, la segunda ejecución del script (37 segundos después) muestra que la primera llamada a la funciónFileReadInteger( ) dio como resultado 21 :34:06, es decir, el tiempo de la última llamada a la funciónFileReadInteger() durante la ejecución del script anterior.

Además, se produce el segundo lanzamiento de la secuencia de comandos a las 21:34:43, lo que significa que la "reapertura de un asa", como usted la llama, se produjo al mismo tiempo. Pero después de tal "reapertura de la manija" devuelve21:34:06, es decir, un tiempo completamente diferente a lo que usted está hablando.

Pregunta 2: ¿cómo debe interpretarse esto?

TheXpert:
Vuelve a abrir el mango y serás feliz.

En la situación actual, se espera una buena noticia cuando se recuperan las propiedades del archivo sin "reabrir" el mango.