与文件一起工作。 - 页 4

[删除]  

TheXpert:

OMG!产出在哪里,就在哪里,这都是胡说八道。这就是我们如何得到 "OOP更快 "或 "指标很慢,我们应该把整个代码放到专家顾问中 "这样的说法。

我理解,一切都没有按计划进行。 至少,正常使用FileFlush()应该比FileClose()快

但我仍然认为你不应该把这种东西放在一个循环里面,反正它们不会有什么帮助。

如果我对MQL4的例子理解正确的话, FileFlush() 的调用 被放在两个循环之间(这让我觉得它是一个循环中的刹车)。

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

因此,如果我对开发者的逻辑理解正确的话,文件应该 在主类的OnInit/构造函数中打开(也许不仅仅是构造函数),在主类的OnDeint/破坏性中关闭。

所有其他情况下 使用 FileFlush 代替FileClose 在FileWrite和循环之后


 

TheXpert:

耶德尔金

我按照文件规定调换了线路。

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

这在文件中写在哪里?

MQL5参考 中,有这样一个短语。

文件刷新

注意事项

FileFlush()函数应该在从文件读取和向文件写入的操作之间被调用。

如果 "写到文件"==FileWrite() 函数,那么就读"FileFlush()函数必须 FileWrite() 函数之前 调用"。还是你有不同的看法?

TheXpert

耶德尔金
我还是不明白FileWrite() 之前调用FileFlush() 的意义。

你怎么能让没有的东西有意义呢? 将各行的顺序返回到主页,并仔细检查。显然,文件中没有把它说得很对。

当你在学习新材料时,提前知道哪些是有意义的,哪些是没有意义的,这是好事。由于大自然没有赋予我们这样的才能,我们必须 "把握每一个新的高度",测试、解释文件和结果。我甚至不确定测试本身是否写得正确。起初我凭直觉把FileFlush()放在FileWrite() 之后,但在重新阅读《手册》后,我删除了这个例子

TheXpert

有趣的 是。

OMG!产量在哪里,这很荒谬。这就是我们如何得到 "OOP更快 "或 "指标很慢,我们应该把整个代码放到专家顾问中 "这样的说法。

如果每一个 "你的输出是愚蠢的 "的评价之后,都能解释它的愚蠢之处,那就更好了:)否则,就不清楚在司法机关如此严格的情况下,应该向什么方向探究 :)

 
TheXpert:

在变化出现之前,没有任何意义,因为它们还没有出现 :)

你不会相信,但正是因为这个原因,我写了 "但 我不明白FileWrite() 之前调用FileFlush() 的意义 ",提到了之前的文档 但我没有足够的胆量和知识去质疑文档中的每一行:)
......好吧,路线很明确--我们在等待开发者的说法,如果真的发现了一些问题。
[删除]  
Yedelkin:

MQL5参考 中,有这样一个短语。

如果 "写到文件"==FileWrite() 函数,它就会读取。"FileFlush()函数必须 FileWrite() 函数之前 调用"。还是你有不同的看法?

让我们分析一下 "相当不幸 "的描述和MQL4 的这个函数的例子。

空白文件冲 刷( int handle)


文件I/O缓冲区中剩余的 所有数据重置到磁盘。

注意:在文件读写操作之间必须调用FileFlush()函数。
当文件被关闭时,数据会自动刷新到磁盘,所以在调用FileClose()之前不需要调用FileFlush()。

这里标记的行是在写进文件之前将FileFlush调用 放在循环 中的必要性的参数。

但如果我们逐字逐句地理解这条评论,就会得到以下结果。

FileFlush()函数必须 从文件读取(而读取是FileReadXXX)和向文件写入(写入是与FileWrite和FileWriteXXX相连)的 操作之间 被调用。

当关闭文件时(读--当FileClose被执行时),数据会自动转储到磁盘(读--当FileFlush被自动执行时)。


我认为,即使在MQL4版本中,开发人员也不太关心阅读帮助的正确性;说要把截断的部分放到MQL5中,甚至是很可笑的。

在我看来,上述评论中的第二句话至少应该是这样的。

当文件被关闭 时, 数据会自动重置到磁盘上,所以在调用FileClose()之前不需要调用FileFlush()。

这也有点乱,但从某种角度来说,它解释了为什么在使用FileClose 关闭文件之前不应该使用FileFlush。


这个例子不是那么简单的,文本说的是一件事(在读和写操作之间的使用),而这个例子描述的是在两个循环写操作之间的使用(顺便说一下,循环内的工作在帮助中根本就没有考虑)。

因此,至少应增加以下内容。

1. 描述这个输入/输出缓冲区是什么,以及在打开文件、读取数据块、写入数据块和关闭文件之间实际发生了什么。

这很可能是指关于文件操作的整个章节。

2.给出一个正常理解的例子(可以是基于类的),说明如何正确使用FileFlush调用进行单一的文件访问(例如写定时器值)。

3 在处理数组时,提供一个正常的调用例子。 据我所知,MQL4参考中描述的例子提到了处理大型数组,但说明的方法不正确(一句话--如果可以做几次,为什么要把相当多的相同数据写两次到文件中?)

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

这里强调的一行是你的论据,即在向文件写入之前需要在循环中调用FileFlush

但如果我们逐字逐句地理解这条评论,就会得到以下结果。

FileFlush()函数 必须 从文件读取(而读取是FileReadXXX)和向文件写入(写入是与FileWrite和FileWriteXXX相连)的 操作之间 调用。

当关闭文件时(读--执行FileClose时),数据将被自动刷入磁盘(读--执行FileFlush时)。

我明白你的意思。对不起,我不知道我把 "从文件中读取 "的操作等同于FileOpen()函数(我的专家顾问只从OnInit()中读取,而在处理ticks和自定义事件时--只写;由于这个原因,我还没有考虑在循环中使用FileReadXXX()这样的函数)。然而,FileFlush()在FileWriteXXX()之前--在这两个参考文献中,原理是一样的。 而且,这并不是经典意义上的论证(作为我的立场的推理),而只是回答我为什么提出这个短语的问题。

总之,如果开发者不在这里回复,我今晚就会发布一个请求,并附上讨论和中间结果的链接。甚至需要两份申请。1)"bug--不是bug",2)文件的变化。既然你对这个话题挖掘得这么深,你愿意自己做第二个申请吗?

[删除]  
Yedelkin:

我知道我在想什么了。我承认,我不自觉地将 "从文件中读取 "的操作等同于函数FileOpen()(我的专家顾问只从OnInit()中读取,而在处理ticks和用户事件 时--只写;由于这个原因,我没有考虑在循环中使用FileReadXXX()等函数)。然而,FileFlush()在FileWriteXXX()之前--在这两个参考文献中,原理是一样的。 而且,这并不是经典意义上的论证(作为我的立场的推理),而只是回答我为什么提出这个短语的问题。

总之,如果开发人员不在这里回复,我今晚就写一个请求,并附上讨论和中间结果的链接。甚至需要两份申请。1)"bug--不是bug",2)文件的变化。既然你对这个问题挖得这么深,你愿意自己提出第二个要求吗?

1.有这么深吗? 如果我明白开发者想说什么,在哪里说,我可能会很乐意去做。

有时会提到I/O缓冲区,但没有对其进行适当的描述。或者这里的每个人都知道FILE I/O缓冲区是什么?

在文件操作一章中加入对这个问题的正常描述是否有困难?或者谷歌在世界各地寻找答案,以了解开发者的想法?

我明白,帮助的规模是有限的,但我们为什么要取笑那些刚刚开始学习MQL的人呢?

2.为什么只有在这个功能的帮助中提到了这个缓冲区,为什么在文件操作部分的其他地方没有提到?

3.让我们假设我对这个输入/输出的缓冲区有一些想法,大约是这样的形式

输入-输出缓冲区 的概念与文件系统有关。输入和输出数据是通过这个缓冲区进行的。

缓冲区是内存中的一个区域,为每个文件分配

在一个文件中的记录,所有的信息首先被引导到缓冲区,并在那里积累,直到缓冲区的所有体积将不会被填满。 只有在这之后或在特殊的转储命令之后 (例如,FileClose或FileFlush)。 数据从缓冲区传输到文件。

当从文件中读取数据时,首先将数据读入缓冲区,并不是要求多少数据就读多少,而是读入多少就放进多少缓冲区。

而开发者真的认为这些都是可以让学习MQL的新人感兴趣的信息(如果只有这个定义可以被认为是对这种语言有效的话)吗?

例如,我想知道这个缓冲区的大小是什么,以及如何定义它。

在我看来,所有这些信息,而不仅仅是这些,都应该在语言文档中(在那里,而不是在论坛上的各种文章和讨论中)。

 
Interesting:
好吧,我自己试着写一份参考资料
 

为什么该脚本不返回文件的实际"最后读取日期"?

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:

为什么该脚本不返回文件的实际"最后读取日期"?

最后访问,而不是读取。重新打开手柄,你就会很高兴。
 
TheXpert:
最后访问,而不是读取访问。

好吧,你可能已经注意到了,在我的问题中,我逐字逐句地引用了文档中的这句话。

enum_file_property_integer

识别器

标识符描述

文件_EXISTS

存在性检查

文件创建日期

创建日期

文件_修改日期

最后修改日期

文件_访问日期

最后一次阅读的日期

问题1:你是否认为文件中有一个错字,应该用 "最后阅读日期 "来代替 "最后打开日期"?至少从你的回答中可以看出,"读取文件 "和 "访问文件 "的操作对你来说意味着不同的东西。

更进一步。如果你多次重启所附脚本,你会看到大致相同的行为。

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

也就是说,当第一次运行脚本时,对FileReadInteger() 的第三次调用发生在21:34:06,但最后一次读取/访问的日期却不同--21:33:57。然而,第二个脚本的运行(37秒后)显示,第一次调用FileReadInteger() 函数的结果是21 :34:06,也就是在上一个 脚本运行过程中 最后一次调用FileReadInteger() 函数的时间。

此外,在21:34:43 发生了脚本的第二次启动,这意味着你所说的 "重新打开一个手柄 "是在同一时间发生的。但在这样的 "手柄重开 "之后,会返回21:34:06,即与你所说的时间完全不同。

问题2:应该如何解释这一点?

TheXpert:
重新打开手柄,你就会很高兴。

在目前的情况下,当文件属性被检索而不需要 "重新打开 "句柄时,预计会有好消息。