文章 "单纯使用 MQL5 语言处理 ZIP 档案" - 页 8 12345678910 新评论 Ivan Titov 2024.03.21 13:27 #71 是否计划添加解压用 GZIP 算法压缩的字符串的功能? Vasiliy Sokolov 2024.03.21 14:44 #72 Ivan Titov CryptEncode(CRYPT_ARCH_ZIP) 系统函数对其进行解压缩。在不使用第三方库的情况下,自己解压缩并不困难,因为压缩算法是一样的,都是 deflate(在 MQL 中,它有一个不太好的标识符CRYPT_ARCH_ZIP)。遗憾的是,没有专门的文章 "使用 MQL5 工具处理 GZip 压缩包"。一般来说,这不是一个系统函数的任务,而是一个特殊的 MQL bibiloteka 的任务,将 deflate 包装成 gzip 格式。 Daniel Santos 2024.08.04 22:04 #73 Jacobie Nycambren Barksdale #: 有什么最新进展吗?我遇到了错误 ZipLocalHeaderOpen' 有构造函数,不能用作联合成员 ZipHeader.mqh 52 23 Jacobie, Stanislav Korotky 在这里发布了一个 包含该 zip 库的软件包,并做了一些修复。 我已经对其进行了测试,目前运行得还不错。 MQL5 Program Packer www.mql5.com This is MQL5 project packer: assemble all source and resource files from dependencies into a single ZIP. Aleksei Kuznetsov 2025.05.31 20:36 #74 我遇到一个 CZip 无法解压的压缩包。 打印出压缩数据的大小 - 结果比压缩包小几十兆字节(其中只有一个文件)。CompressedSize:76964920 我开始寻找计算的地方,结果在 FindZipFileSize() 函数中找到了。 经过实验...... 结果发现,如果将所有 end_size 数据作为数据大小返回,压缩包就能正确解压缩。显然,在解压缩时,代码本身会确定数据的结束,而不是依赖该函数的响应。主要问题是,它不应该更小。 你可以让它保持这样,但结果是该函数毫无用处,这不太可能。也许还有其他存档会失败...... 还有一个实验表明,如果注释掉以下几行 // if(pattern == cdheader) // break;存档也会开始解包。数据量接近 100%。CompressedSize:106638447 原来,压缩包中有 uint cdheader =0x504b0102;这是压缩数据的一部分,而不是其结尾的标签。 你是不是弄错了标签?我在网上搜索到过这样的标签。也许应该用其他方法来处理它,而不是用它来剪切数据,我剪切了 30MB。 Function working with this file: (file\Include\Zip\Zip\Zip.mqh)int CZip::FindZipFileSize(uchar &zip_array[],int offset) { uint pattern = 0; int size = 0; uint header = 0x504b0304; uint cdheader = 0x504b0102; uint mask = 0xffff0000; int end_size = ArraySize(zip_array)-offset; //这是基于字节左移的环形缓冲区: x = x << 8 for(; size < end_size; size++) { pattern = pattern << 8; uint nbyte = zip_array[offset+size]; pattern = pattern | nbyte; //检查上面 2 个字节 if((pattern & mask)!=(0x504b << 16)) continue; //如果上面两个字节等于 0x504b 检查所有签名 if(pattern == header) break; // if(pattern == cdheader) // break; } //未找到签名。格式错误。 if(size == end_size-1) return 0; //Return 尺寸 - 签名尺寸。 return size-sizeof(ZIP_LOCAL_HEADER)+1; } 如果你有兴趣弄明白,我可以通过私人信息把存档文件发给你。 Aleksei Kuznetsov 2025.06.01 13:22 #75 另一个文件又出错了。这次注释行帮了大忙 // if(pattern == header) // break; 即代码 uint header = 0x504b0304; 也出现在存档内容中,并被 7Zip、Windows 和此更正版本的 CZip 成功解压缩。 由于两个循环退出都被禁用,循环已变得多余,可以删除并返回: return ArraySize(zip_array)-offset-sizeof(ZIP_LOCAL_HEADER)+1; 这个函数显然存在缺陷。毕竟,条件 //未找到签名。格式错误。 if(size == end_size-1) return 0; 条件永远不会满足,因为当数据结束时退出循环,size == end_size 将是 size == end_size,而不是少 1。 因此,我将函数缩短为一行: int CZip::FindZipFileSize(const uchar &zip_array[],int offset) { /*uint pattern = 0; int size =0; uint header = 0x504b0304; uint cdheader =0x504b0102; uint mask = 0xffffff0000; int end_size = ArraySize(zip_array)-offset; //this is ring buffer based on byte left shift:x = x << 8 for(; size < end_size; size++) { pattern = pattern << 8; uint nbyte = zip_array[offset+size]; pattern = pattern | nbyte; //check upper 2 bytes if((pattern & mask)!=(0x504b << 16)) continue; //if two upper bytes equal 0x504b check all signatures // if(pattern == header) //break; // if(pattern == cdheader) //break; } // 没有找到签名。 if(size == end_size-1) return 0; //Return size - signature size. return size-size-sizeof(ZIP_LOCAL_HEADER)+1; */ return ArraySize(zip_array)-offset-sizeof(ZIP_LOCAL_HEADER)+1; } 如果有人在解包时遇到问题,可以试试这个版本的函数。 Aleksei Kuznetsov 2025.06.01 21:12 #76 下载并解压了近 300 个文件。其中的数据越来越大,已经达到了大小限制。 文件应该有 18 亿个字符元素,但解压缩后只剩下 15 亿个。 一些数据丢失了。 终端函数 生成剪切数据。 CryptDecode(CRYPT_ARCH_ZIP, m_file_puck, key, file_array);对此没有任何办法...我认为可以用偶数 kb/mb 块进行解码 - 我提供了 1024、1024*1024 和 1024*1024*10,但没有成功。 我必须先保存存档,然后手动解压缩,再进行处理。如果没有自动化,这将会很不方便(( 有什么办法可以使用 Windows 存档器吗?使用 WinExec 解压到文件中,然后逐行读取。这样就能保持自动化。但不适合市场。 Edgar Akhmadeev 2025.06.01 21:45 #77 Forester #: 有什么办法可以使用 Windows 存档程序吗?使用 WinExec 解压到文件,然后逐行读取。 显然可以。问题出在哪里?也许我理解错了?很早以前就有 UnRAR.exe、UnZip.exe 等控制台压缩器了。 Aleksei Kuznetsov 2025.06.09 05:38 #78 Forester #:另一个文件又出错了。这一次,注释行帮了大忙 即代码 uint header = 0x504b0304; 也出现在存档内容中,并被 7Zip、Windows 和修正版 CZip 成功解压缩。 由于两个循环退出都被禁用,循环已变得多余,可以删除并返回:这个函数显然存在缺陷。毕竟,条件 条件永远不会满足,因为在数据结束时退出循环时,size == end_size 将是 size == end_size,而不是少 1。因此,我将函数缩短为一行: 如果有人在解包时遇到问题,可以试试这个版本的函数。 我认为您仍然需要搜索标签,但不是在存档正文中,而是在文件之间(如果有多个文件)。可能应在某处记录存档长度....。 一般来说,我的解决方案是针对存档中只有一个文件的任务而设计的,如果存档中有多个文件--也许你需要做其他事情。 Aleksei Kuznetsov 2025.06.09 07:11 #79 Forester #:我可以假定标签仍然需要搜索,但不是在存档正文中,而是在文件之间,如果有几个文件的话。可能应在某处记录存档的长度....。 总的来说,我的解决方案对我的任务来说是私人的,只需在存档中搜索一个文件,如果有多个文件,也许就需要做其他事情了。 我打印了压缩和未压缩的大小,这些大小应该出现在文件头中。 我下载的那些文件 - 大小为 0 0。如果 size=0,则调用上面讨论的 FindZipFileSize()。我使用普通压缩器将第一个文件创建了一个压缩包。文件头中的大小:46389587 376516461另一个存档包含另外 2 个文件,包括添加到第一个存档中的文件: 46981880 31472504546389587 376516461 这两个文件的大小都写在文件头中,并且没有调用 FindZipFileSize() 而我下载的文件(大小为 0 0)显然是由没有在文件头中写入大小的软件创建的。 也许我缩短 FindZipFileSize() 的解决方案是通用的。 Aleksei Kuznetsov 2025.06.14 18:26 #80 Edgar Akhmadeev #:我们当然可以。有什么问题吗?也许我理解错了?很早以前就有 UnRAR.exe、UnZip.exe 等控制台存档程序了。 我通过 7-zip 进行了解压(UnZip.exe 自 2009 年以来就没有更新过,甚至 Win 7 的支持也没有写)。 我比较了一下速度: 这个 CZIP 库: 2025.06.14 20:59:06.758 存档成功打开。文件总数:1。 2025.06.14 20:59:07.345 未压缩587ms 7-zip: 2025.06.14 21:00:07.312 通过 7-Zip 开始解压缩。 2025.06.14 21:00:09.274 通过 7-Zip 解压缩。文件大小:428.22 MB1962 ms 这只是将文件解压缩并重置到固态硬盘磁盘。你还必须从光盘中逐行读取文件。 解析从开始到结束的总时间: 总时间:10 秒 709ms 和 总时间:12 秒 892ms 相差 2 秒 183 毫秒。 一般来说,为了提高速度,最好使用这个 CZIP 库,如果文件太大,可以使用其他存档器。 对我来说,以每个文件 2 秒的速度处理约 1000 个文件,可节省 33 分钟。实际上更多,因为这是一个最小文件为 428 MB 的例子,CZIP 解压缩的文件最大可达 ~1.7GB。 更大的文件(最多 4GB)则由 7-zip 处理。因此可以节省 1-1.5 个小时。 我用自己编辑的文件对 CZIP 进行了测试,解压了 100GB 的 600 多个文件,没有出现任何错误。 Discussion of article "Handling 使用 OpenCL 测试烛形形态 12345678910 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
有什么最新进展吗?我遇到了错误
Jacobie, Stanislav Korotky 在这里发布了一个 包含该 zip 库的软件包,并做了一些修复。
我已经对其进行了测试,目前运行得还不错。
我遇到一个 CZip 无法解压的压缩包。
打印出压缩数据的大小 - 结果比压缩包小几十兆字节(其中只有一个文件)。
CompressedSize:76964920我开始寻找计算的地方,结果在 FindZipFileSize() 函数中找到了。经过实验......
结果发现,如果将所有 end_size 数据作为数据大小返回,压缩包就能正确解压缩。显然,在解压缩时,代码本身会确定数据的结束,而不是依赖该函数的响应。主要问题是,它不应该更小。 你可以让它保持这样,但结果是该函数毫无用处,这不太可能。也许还有其他存档会失败......
还有一个实验表明,如果注释掉以下几行
存档也会开始解包。数据量接近 100%。
CompressedSize:106638447原来,压缩包中有 uint cdheader =0x504b0102;这是压缩数据的一部分,而不是其结尾的标签。你是不是弄错了标签?我在网上搜索到过这样的标签。也许应该用其他方法来处理它,而不是用它来剪切数据,我剪切了 30MB。
如果你有兴趣弄明白,我可以通过私人信息把存档文件发给你。Function working with this file: (file\Include\Zip\Zip\Zip.mqh)
另一个文件又出错了。这次注释行帮了大忙
即代码 uint header = 0x504b0304; 也出现在存档内容中,并被 7Zip、Windows 和此更正版本的 CZip 成功解压缩。
由于两个循环退出都被禁用,循环已变得多余,可以删除并返回:
这个函数显然存在缺陷。毕竟,条件
条件永远不会满足,因为当数据结束时退出循环,size == end_size 将是 size == end_size,而不是少 1。
因此,我将函数缩短为一行:
如果有人在解包时遇到问题,可以试试这个版本的函数。
文件应该有 18 亿个字符元素,但解压缩后只剩下 15 亿个。 一些数据丢失了。
终端函数
生成剪切数据。
对此没有任何办法...
我认为可以用偶数 kb/mb 块进行解码 - 我提供了 1024、1024*1024 和 1024*1024*10,但没有成功。
有什么办法可以使用 Windows 存档器吗?使用 WinExec 解压到文件中,然后逐行读取。这样就能保持自动化。但不适合市场。我必须先保存存档,然后手动解压缩,再进行处理。如果没有自动化,这将会很不方便((
有什么办法可以使用 Windows 存档程序吗?使用 WinExec 解压到文件,然后逐行读取。
显然可以。问题出在哪里?也许我理解错了?很早以前就有 UnRAR.exe、UnZip.exe 等控制台压缩器了。
另一个文件又出错了。这一次,注释行帮了大忙
即代码 uint header = 0x504b0304; 也出现在存档内容中,并被 7Zip、Windows 和修正版 CZip 成功解压缩。
由于两个循环退出都被禁用,循环已变得多余,可以删除并返回:
这个函数显然存在缺陷。毕竟,条件
条件永远不会满足,因为在数据结束时退出循环时,size == end_size 将是 size == end_size,而不是少 1。
因此,我将函数缩短为一行:
如果有人在解包时遇到问题,可以试试这个版本的函数。
我认为您仍然需要搜索标签,但不是在存档正文中,而是在文件之间(如果有多个文件)。可能应在某处记录存档长度....。
一般来说,我的解决方案是针对存档中只有一个文件的任务而设计的,如果存档中有多个文件--也许你需要做其他事情。
我可以假定标签仍然需要搜索,但不是在存档正文中,而是在文件之间,如果有几个文件的话。可能应在某处记录存档的长度....。
总的来说,我的解决方案对我的任务来说是私人的,只需在存档中搜索一个文件,如果有多个文件,也许就需要做其他事情了。
我打印了压缩和未压缩的大小,这些大小应该出现在文件头中。
我下载的那些文件 - 大小为 0 0。如果 size=0,则调用上面讨论的 FindZipFileSize()。
我使用普通压缩器将第一个文件创建了一个压缩包。文件头中的大小:
46389587 376516461
另一个存档包含另外 2 个文件,包括添加到第一个存档中的文件:
46981880 314725045
46389587 376516461
这两个文件的大小都写在文件头中,并且没有调用 FindZipFileSize()
而我下载的文件(大小为 0 0)显然是由没有在文件头中写入大小的软件创建的。也许我缩短 FindZipFileSize() 的解决方案是通用的。
我们当然可以。有什么问题吗?也许我理解错了?很早以前就有 UnRAR.exe、UnZip.exe 等控制台存档程序了。
我通过 7-zip 进行了解压(UnZip.exe 自 2009 年以来就没有更新过,甚至 Win 7 的支持也没有写)。
我比较了一下速度:
这个 CZIP 库:
2025.06.14 20:59:06.758 存档成功打开。文件总数:1。
2025.06.14 20:59:07.345 未压缩
587ms
7-zip:
2025.06.14 21:00:07.312 通过 7-Zip 开始解压缩。
2025.06.14 21:00:09.274 通过 7-Zip 解压缩。文件大小:428.22 MB
1962 ms
这只是将文件解压缩并重置到固态硬盘磁盘。你还必须从光盘中逐行读取文件。
解析从开始到结束的总时间:
总时间:10 秒 709ms
和
总时间:12 秒 892ms
相差 2 秒 183 毫秒。
一般来说,为了提高速度,最好使用这个 CZIP 库,如果文件太大,可以使用其他存档器。
对我来说,以每个文件 2 秒的速度处理约 1000 个文件,可节省 33 分钟。实际上更多,因为这是一个最小文件为 428 MB 的例子,CZIP 解压缩的文件最大可达 ~1.7GB。
更大的文件(最多 4GB)则由 7-zip 处理。因此可以节省 1-1.5 个小时。
我用自己编辑的文件对 CZIP 进行了测试,解压了 100GB 的 600 多个文件,没有出现任何错误。