文章 "单纯使用 MQL5 语言处理 ZIP 档案" - 页 9 12345678910 新评论 Aleksei Kuznetsov 2025.06.15 10:00 #81 Forester #: 下载并解压了近 300 个文件。其中的数据越来越大,已经达到了大小限制。文件应该有 18 亿个字符元素,但解压缩后只剩下 15 亿个。 一些数据丢失了。很奇怪,数组可以有多达2147483647 个 元素。 。 我整理了超过一定容量(不同文件从 1.7GB 到 2136507776 - 即几乎达到 MAX_INT=2147483647,数组不能有更多元素)且在输出时被切断的文件(解压缩)。结果发现它们都被标记为错误: CryptDecode(CRYPT_ARCH_ZIP, m_file_puck, key, file_array); 但 CZIP 无法控制这一点。我将输出数组的大小归零。 因此,在我的函数中,我可以 100% 保证文件已成功解压缩。 在此之前,我检查了 JSON 文件的正确结尾 }\r\n - 但这一解决方案并不通用,在 ~1000 个文件中,似乎有几个文件不小心被中间行截断,并被视为成功解压缩,但其中的数据并不完整。 新版本的函数: 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);}//将大小重置为 0 } else { ArrayCopy(file_array, m_file_puck); } } 新版本以黄色 标出。 也许开发人员还应该将数组重置为零,因为几乎没有人需要经过修剪的数据。而且可能会导致难以察觉的错误。 Stanislav Korotky 2025.06.15 11:40 #82 Forester #:我整理了超过一定容量(不同文件的容量从 1.7Gb 到 2136507776 - 即几乎达到 MAX_INT=2147483647,数组不能有更多元素)且在输出时被切断的文件(已解压缩)。结果发现,所有这些文件都被标记为错误文件: 但 CZIP 无法控制这一点。我将输出数组的大小清零。 因此,在我的函数中,我可以 100% 保证文件已成功解压缩。 在此之前,我检查了 JSON 文件的正确结尾 }\r\n - 但这一解决方案并不通用,在 ~1000 个文件中,似乎有几个文件被中间行意外截断,并被视为成功解压缩,但其中的数据并不完整。 新版本的函数:新版本以黄色 标出。也许开发人员还应该将数组重置为零,因为几乎没有人需要经过修剪的数据。而且可能会导致难以察觉的错误。 首先,对于解压缩 zip 而言,返回值为 0 并不是一个 100% 的错误信号(这可能是该函数仅用于加密而非压缩时遗留下来的--也许应该修改,但他们不太可能这么做,以免破坏向后兼容性),因为 zip 纯粹是在技术上允许归档空数据("接收器数组 "将合法为空,不会出现任何错误)。 其次,部分解压缩数据的存在可能对错误诊断有用,因此最好保留它们。 Aleksei Kuznetsov 2025.06.15 12:06 #83 Stanislav Korotky #:首先,返回值为 0 并不 100% 表示出错在我处理的约 1000 个文件中,返回值为 0 的标签让我放弃了所有按文件末尾模式搜索的文件(即 100% 有效),以及另外 5 个显然被行末尾剪切的文件。 所以它比我的方法更可靠。其次,部分未打包数据的存在可能有助于诊断错误,因此最好保留它们。 在我的案例中,还剩下大约 5 个被剪切的文件,它们的结束方式与预期的文件结束方式相同,无法用任何其他方式进行检查--也就是说,这不是错误诊断,而是工作算法中的错误跳过。 您的错误诊断选项?不过,我自己已经解决了这个问题。但在我弄懂别人的代码之前,错误是被跳过的。如果 MT 方面进行了归零,错误就不会出现。 一般来说,支持和反对的意见都有。开发人员将决定哪种方法更好/更符合逻辑。 PS.如果压缩文件长度为 0,可以添加 -1 表示压缩错误。 Stanislav Korotky 2025.06.15 13:42 #84 Forester #:在我的案例中,大约有 5 个被剪切的文件,它们的结尾与预期的文件结尾一样,无法再以任何方式进行检查--也就是说,这不是错误诊断,而是工作算法中的跳错。您有哪些错误诊断方案?不过,我自己已经解决了这个问题。但在我弄明白别人的代码之前,错误是被跳过的。如果 MT 方面进行了重置,这些错误就不会出现。 我不明白错误怎么会被跳过。函数返回的数据不为零,而且数组被填满,存档数据部分丢失?那么这是 MQL5 中的一个错误 - 应该在那里纠正。 是否检查了 _LastError 标志? 不应该设置 "预计文件结束",因为归档是一个通用的事情 - 我们可能不知道接收文件的格式。 Aleksei Kuznetsov 2025.06.15 14:05 #85 Stanislav Korotky #:我没有意识到错误是如何被遗漏的。 这是文章中 CZIP 库的一个缺陷。没有检查解压缩的结果。只是 CryptDecode(CRYPT_ARCH_ZIP, m_file_puck, key, file_array); 就在今天,我发现了这一点,并添加了黄色高亮显示的检查。 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);}//将大小重置为 0 刚开始使用时,我并没有意识到没有检查--这就是为什么我为文件的预期结束设置了检查。 永远都不应该设置 "预期文件结束",因为归档是一件很笼统的事情--我们可能不知道接收到的文件格式。 我同意,这就是我为什么要在出现错误时将数组清零。 除了文件大小为 0 的情况,这是最普遍的做法。 但即使文件大小为 0,我也不会处理/解析 JSON,也没有人会处理/解析 JSON,因为如果元素数为 0,就不会启动元素循环,所以在我看来,将数组清零是一个很好的解决方案。 fxsaber 2025.08.21 10:41 #86 附件是针对MQL5 新版本 (b5223+) 对库代码进行的小修改。 Новая версия платформы MetaTrader 5 build 5200: расширение OpenBLAS и усиление контроля в MQL5 2025.08.20www.mql5.com В пятницу 1 августа 2025 года будет выпущена обновленная версия платформы MetaTrader 5... 附加的文件: ZipHeader.mqh 27 kb Vasiliy Sokolov 2025.08.29 10:11 #87 Forester #:我遇到一个 CZip 无法解压的压缩包。 打印出了压缩数据的大小--结果比压缩包少了几十兆字节(其中只有一个文件)。 我开始寻找计算的地方,结果在 FindZipFileSize() 函数中找到了。 经过实验...... 结果发现,如果将所有 end_size 数据作为数据大小返回,压缩包就能正确解压缩。显然,在解压缩时,代码本身会确定数据的结束,而不是依赖该函数的响应。主要问题是,它不应该更小。 你可以让它保持这样,但结果是该函数毫无用处,这不太可能。也许还有其他存档会失败...... 还有一个实验表明,如果注释掉以下几行存档也会开始解包。数据量接近 100%。 原来,压缩包中有 uint cdheader =0x504b0102;,而这是压缩数据的一部分,而不是其结尾的标签。 你是不是弄错了标签?我在网上搜索到过这样的标签。也许应该用其他方法来处理,而不是用它来剪切数据,我剪切了 30MB。 Function working with this file: (file\Include\Zip\Zip.mqh). 如果你有兴趣弄明白,我可以把存档文件以私信的形式发给你。 问题是,有一种 Zip 格式,它有精确的规范和描述,有各种打包程序(windows、total commander、7zip 等),它们都基于这一标准,而且在填充头结构时都很有创意。因此,CZip 无法依赖格式的正确填写,只能自行计算。必须解决 标识符0x504b0102 的问题。 我们应该再次修改代码,并根据您的宝贵意见推出有效的更新。很高兴有人在使用这个库。 Vasiliy Sokolov 2025.08.29 10:43 #88 fxsaber #: 随函附上针对MQL5 新版本 (b5223+) 的 库代码小修改。 谢谢。MQL5 越来越无知和无情。 如果 MetaQuotes 最终实现了标准反射和序列化功能,99% 的错误都可以避免。 Vasiliy Sokolov 2025.08.29 11:06 #89 Forester #:我遇到一个 CZip 无法解压的压缩包。不过,7ZIP 和 Windows 存档器却能顺利解压。... 如果您有兴趣了解,我可以通过私人信息将存档文件发送给您。 请将存档文件以私人消息的形式发送给我。 Aleksei Kuznetsov 2025.08.29 12:55 #90 Vasiliy Sokolov #:请通过私人信息将存档文件发给我。 https://quote-saver.bycsi.com/orderbook/linear/BTCUSDT/2023-01-18_BTCUSDT_ob500.data.zip 在存档正文中(而不是在文件头中)有 cdheader = 0x504b0102; 在下一个日期文件中也有。 header = 0x504b0304; 出现在每个文件的页眉中,即前 4 个字符。 但它也出现在存档正文中,但很少出现。 这里是https://quote-saver.bycsi.com/orderbook/linear/BTCUSDT/2023-03-15_BTCUSDT_ob500.data.zip。 我认为有必要只在档案正文中搜索这些标题。 12345678910 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
下载并解压了近 300 个文件。其中的数据越来越大,已经达到了大小限制。文件应该有 18 亿个字符元素,但解压缩后只剩下 15 亿个。 一些数据丢失了。很奇怪,数组可以有多达
2147483647 个 元素。 。
我整理了超过一定容量(不同文件从 1.7GB 到 2136507776 - 即几乎达到 MAX_INT=2147483647,数组不能有更多元素)且在输出时被切断的文件(解压缩)。结果发现它们都被标记为错误:
但 CZIP 无法控制这一点。我将输出数组的大小归零。
因此,在我的函数中,我可以 100% 保证文件已成功解压缩。
在此之前,我检查了 JSON 文件的正确结尾 }\r\n - 但这一解决方案并不通用,在 ~1000 个文件中,似乎有几个文件不小心被中间行截断,并被视为成功解压缩,但其中的数据并不完整。
新版本的函数:
新版本以黄色 标出。
也许开发人员还应该将数组重置为零,因为几乎没有人需要经过修剪的数据。而且可能会导致难以察觉的错误。
我整理了超过一定容量(不同文件的容量从 1.7Gb 到 2136507776 - 即几乎达到 MAX_INT=2147483647,数组不能有更多元素)且在输出时被切断的文件(已解压缩)。结果发现,所有这些文件都被标记为错误文件:
但 CZIP 无法控制这一点。我将输出数组的大小清零。
因此,在我的函数中,我可以 100% 保证文件已成功解压缩。
在此之前,我检查了 JSON 文件的正确结尾 }\r\n - 但这一解决方案并不通用,在 ~1000 个文件中,似乎有几个文件被中间行意外截断,并被视为成功解压缩,但其中的数据并不完整。
新版本的函数:
新版本以黄色 标出。
也许开发人员还应该将数组重置为零,因为几乎没有人需要经过修剪的数据。而且可能会导致难以察觉的错误。
首先,对于解压缩 zip 而言,返回值为 0 并不是一个 100% 的错误信号(这可能是该函数仅用于加密而非压缩时遗留下来的--也许应该修改,但他们不太可能这么做,以免破坏向后兼容性),因为 zip 纯粹是在技术上允许归档空数据("接收器数组 "将合法为空,不会出现任何错误)。
其次,部分解压缩数据的存在可能对错误诊断有用,因此最好保留它们。
首先,返回值为 0 并不 100% 表示出错
在我处理的约 1000 个文件中,返回值为 0 的标签让我放弃了所有按文件末尾模式搜索的文件(即 100% 有效),以及另外 5 个显然被行末尾剪切的文件。
所以它比我的方法更可靠。
在我的案例中,还剩下大约 5 个被剪切的文件,它们的结束方式与预期的文件结束方式相同,无法用任何其他方式进行检查--也就是说,这不是错误诊断,而是工作算法中的错误跳过。
您的错误诊断选项?
不过,我自己已经解决了这个问题。但在我弄懂别人的代码之前,错误是被跳过的。如果 MT 方面进行了归零,错误就不会出现。
PS.如果压缩文件长度为 0,可以添加 -1 表示压缩错误。一般来说,支持和反对的意见都有。开发人员将决定哪种方法更好/更符合逻辑。
在我的案例中,大约有 5 个被剪切的文件,它们的结尾与预期的文件结尾一样,无法再以任何方式进行检查--也就是说,这不是错误诊断,而是工作算法中的跳错。
您有哪些错误诊断方案?
不过,我自己已经解决了这个问题。但在我弄明白别人的代码之前,错误是被跳过的。如果 MT 方面进行了重置,这些错误就不会出现。
我不明白错误怎么会被跳过。函数返回的数据不为零,而且数组被填满,存档数据部分丢失?那么这是 MQL5 中的一个错误 - 应该在那里纠正。
是否检查了 _LastError 标志?
不应该设置 "预计文件结束",因为归档是一个通用的事情 - 我们可能不知道接收文件的格式。
我没有意识到错误是如何被遗漏的。
这是文章中 CZIP 库的一个缺陷。没有检查解压缩的结果。只是
就在今天,我发现了这一点,并添加了黄色高亮显示的检查。
刚开始使用时,我并没有意识到没有检查--这就是为什么我为文件的预期结束设置了检查。
我同意,这就是我为什么要在出现错误时将数组清零。
除了文件大小为 0 的情况,这是最普遍的做法。
但即使文件大小为 0,我也不会处理/解析 JSON,也没有人会处理/解析 JSON,因为如果元素数为 0,就不会启动元素循环,所以在我看来,将数组清零是一个很好的解决方案。
我遇到一个 CZip 无法解压的压缩包。
我开始寻找计算的地方,结果在 FindZipFileSize() 函数中找到了。打印出了压缩数据的大小--结果比压缩包少了几十兆字节(其中只有一个文件)。
经过实验......
结果发现,如果将所有 end_size 数据作为数据大小返回,压缩包就能正确解压缩。显然,在解压缩时,代码本身会确定数据的结束,而不是依赖该函数的响应。主要问题是,它不应该更小。 你可以让它保持这样,但结果是该函数毫无用处,这不太可能。也许还有其他存档会失败......
还有一个实验表明,如果注释掉以下几行
存档也会开始解包。数据量接近 100%。
原来,压缩包中有 uint cdheader =0x504b0102;,而这是压缩数据的一部分,而不是其结尾的标签。你是不是弄错了标签?我在网上搜索到过这样的标签。也许应该用其他方法来处理,而不是用它来剪切数据,我剪切了 30MB。
如果你有兴趣弄明白,我可以把存档文件以私信的形式发给你。Function working with this file: (file\Include\Zip\Zip.mqh).
问题是,有一种 Zip 格式,它有精确的规范和描述,有各种打包程序(windows、total commander、7zip 等),它们都基于这一标准,而且在填充头结构时都很有创意。因此,CZip 无法依赖格式的正确填写,只能自行计算。必须解决 标识符0x504b0102 的问题。
我们应该再次修改代码,并根据您的宝贵意见推出有效的更新。很高兴有人在使用这个库。
随函附上针对MQL5 新版本 (b5223+) 的 库代码小修改。
谢谢。MQL5 越来越无知和无情。
如果 MetaQuotes 最终实现了标准反射和序列化功能,99% 的错误都可以避免。
我遇到一个 CZip 无法解压的压缩包。不过,7ZIP 和 Windows 存档器却能顺利解压。
...
如果您有兴趣了解,我可以通过私人信息将存档文件发送给您。请将存档文件以私人消息的形式发送给我。
请通过私人信息将存档文件发给我。
https://quote-saver.bycsi.com/orderbook/linear/BTCUSDT/2023-01-18_BTCUSDT_ob500.data.zip
在存档正文中(而不是在文件头中)有 cdheader = 0x504b0102;
在下一个日期文件中也有。
header = 0x504b0304; 出现在每个文件的页眉中,即前 4 个字符。
但它也出现在存档正文中,但很少出现。
这里是https://quote-saver.bycsi.com/orderbook/linear/BTCUSDT/2023-03-15_BTCUSDT_ob500.data.zip。
我认为有必要只在档案正文中搜索这些标题。