信息存储方法:文本和二进制
在前面多个章节中,我们已经知道,相同的信息可以以文本和二进制形式表示。例如,int、long 数字和 double 格式、日期和时间 (datetime) 以及颜色 (color) 均以一定长度的字节序列存储在内存中。该方法比较紧凑,更适合计算机解读,但对于人类来说,以文本形式分析信息更为方便,虽然其长度更长。因此,我们更多地关注于 数字与字符串的相互转换以及 用于处理字符串的函数。
在文件层面,仍然保留了数据的二进制和文本表示的划分。二进制文件设计用于以内存中使用的相同内部表示来存储数据。文本文件包含字符串表示。
文本文件通常用于标准格式,诸如 CSV(逗号分隔值)、JSON(JavaScript 对象表示法)、XML(可扩展标记语言)、HTML(超文本标记语言)。
二进制文件当然也具有用于多种应用程序的标准格式,尤其是图像(PNG、GIF、JPG 和 BMP)、声音(WAV、MP3)或压缩档案 (ZIP)。然而,二进制格式在一开始需要更大的数据保护和低层级的数据处理,因此更常用于解决内部问题 ―― 此时仅需关注存储效率和特定程序的数据可用性。换言之,任何应用结构体和类对象都可轻松在二进制文件中保存和恢复状态(实际生成内存快照),无需担心与任何标准的兼容性。
理论上,当写入二进制文件时,我们可以手动将数据转换为字符串,然后在读取文件时从字符串转换回数字(或结构体或数组)。这应会类似于文本文件模式自动提供的功能,但应还需要额外的人工。文本文件模式为我们省却了该项例行工作。此外,MQL5 文件子系统会隐式执行一些可选操作,但却是处理文本时所需的重要操作。
首先,文本概念是基于一些使用定界符字符的一般规则。尤其是假定所有文本均由字符串组成。这样在算法上更方便读取和分析。因此,有将一个特殊字符可用于将不同字符串分隔开。
这里我们面临第一个难点:操作系统不同,接受的分隔符组合也不同。在 Windows 中,行分隔符是两个字符 '\r\n' 构成的序列(十六进制代码为:0xD 0xA,或者作为名称 CRLF,代表回车和换行)。在 Unix 和 Linux 中,标准分隔符是单字符 '\n',但在 MacOS 中的一些版本和程序可能使用单字符 '\r'。
虽然 MetaTrader 5 是在 Windows 下运行,但是我们不能保证任何生成的文本文件保存后都将不会带有异常分隔符。如果我们要以二进制模式读取,并自行检查定界符以形成字符串,则这些不一致将需要特定处理。在这里,MQL5 中的文件操作的文本模式可派上用场:该模式可在读写时自动标准化换行符。
MQL5 不一定在所有情况下均能够修复换行符。尤其是在读取文本文件时,单字符 '\r' 无法被解读为 '\r\n',而单字符 '\n' 可以被正确解读为 '\r\n'。
其次,字符串可以以多种表示方式存储在内存中。默认情况下,MQL5 中的字符串( 字符串类型)由两字节 字符组成。这提供了对通用 Unicode 编码的支持,这很好,因为 Unicode 包括了各国文字。然而很多情况下并不需要这种通用性(例如以英文存储数字或消息时),若是不需要这种通用性,使用 ANSI 编码的单字节字符更高效。MQL5 API 函数允许你选择以文本模式将字符串写入文件的首先方式。但是如果我们控制在我们的 MQL 程序中的写入,则我们可以保证从 Unicode 切换到单字节字符的有效性和可靠性。在此情况下,与某些外部软件或 Web 服务集成时,其文件中的 ANSI 代码页可能是任何语言的。由此引出了下一个要点。
第三点,由于存在多种不同的语言,你需要准备好处理各种 ANSI 编码的文本。如果无法正确解析编码,文本读写时可能会出现乱码,甚至无法读取。我们已在 处理符号和代码页中了解过它。因此,文件函数包含了用于正确字符处理的方法:只需在参数中指定所需或预期的编码即可。编码选择在 单独章节中详细介绍。
最后,文本模式内置支持流行的 CSV 格式。由于交易通常要求使用表数据,CSV 很适合于这类用途。在 CSV 模式的文本文件中,MQL5 API 函数不仅处理用于文本换行的定界符,而且处理用于列边框(表每行中的字段)的附加定界符。这通常是制表符 '\t'、逗号 ',' 或者分号 ';'。例如,一个包含外汇资讯的 CSV 文件大致如下所示(显示逗号分隔的部分):
Title,Country,Date,Time,Impact,Forecast,Previous
|
为便于清晰易懂,表形式如下:
Title |
Country |
Date |
Time |
Impact |
Forecast |
Previous |
---|---|---|---|---|---|---|
Bank Holiday |
JPY |
08-09-2021 |
12:00am |
Holiday |
|
|
CPI y/y |
CNY |
08-09-2021 |
1:30am |
Low |
0.8% |
1.1% |
PPI y/y |
CNY |
08-09-2021 |
1:30am |
Low |
8.6% |
8.8% |
Unemployment Rate |
CHF |
08-09-2021 |
5:45am |
Low |
3.0% |
3.1% |
German Trade Balance |
EUR |
08-09-2021 |
6:00am |
Low |
13.9B |
12.6B |
Sentix Investor Confidence |
EUR |
08-09-2021 |
8:30am |
Low |
29.2 |
29.8 |
JOLTS Job Openings |
USD |
08-09-2021 |
2:00pm |
Medium |
9.27M |
9.21M |
FOMC Member Bostic Speaks |
USD |
08-09-2021 |
2:00pm |
Medium |
|
|
FOMC Member Barkin Speaks |
USD |
08-09-2021 |
4:00pm |
Medium |
|
|
BRC Retail Sales Monitor y/y |
GBP |
08-09-2021 |
11:01pm |
Low |
4.9% |
6.7% |
Current Account |
JPY |
08-09-2021 |
11:50pm |
Low |
1.71T |
1.87T |