文章 "单纯使用 MQL5 语言处理 ZIP 档案" - 页 9

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

新版本以黄色 标出。

也许开发人员还应该将数组重置为零,因为几乎没有人需要经过修剪的数据。而且可能会导致难以察觉的错误。

 
Forester #:

我整理了超过一定容量(不同文件的容量从 1.7Gb 到 2136507776 - 即几乎达到 MAX_INT=2147483647,数组不能有更多元素)且在输出时被切断的文件(已解压缩)。结果发现,所有这些文件都被标记为错误文件:


但 CZIP 无法控制这一点。我将输出数组的大小清零。
因此,在我的函数中,我可以 100% 保证文件已成功解压缩。
在此之前,我检查了 JSON 文件的正确结尾 }\r\n - 但这一解决方案并不通用,在 ~1000 个文件中,似乎有几个文件被中间行意外截断,并被视为成功解压缩,但其中的数据并不完整。

新版本的函数:

新版本以黄色 标出。

也许开发人员还应该将数组重置为零,因为几乎没有人需要经过修剪的数据。而且可能会导致难以察觉的错误。

首先,对于解压缩 zip 而言,返回值为 0 并不是一个 100% 的错误信号(这可能是该函数仅用于加密而非压缩时遗留下来的--也许应该修改,但他们不太可能这么做,以免破坏向后兼容性),因为 zip 纯粹是在技术上允许归档空数据("接收器数组 "将合法为空,不会出现任何错误)。

其次,部分解压缩数据的存在可能对错误诊断有用,因此最好保留它们。

 
Stanislav Korotky #:

首先,返回值为 0 并不 100% 表示出错

在我处理的约 1000 个文件中,返回值为 0 的标签让我放弃了所有按文件末尾模式搜索的文件(即 100% 有效),以及另外 5 个显然被行末尾剪切的文件。
所以它比我的方法更可靠。

其次,部分未打包数据的存在可能有助于诊断错误,因此最好保留它们。

在我的案例中,还剩下大约 5 个被剪切的文件,它们的结束方式与预期的文件结束方式相同,无法用任何其他方式进行检查--也就是说,这不是错误诊断,而是工作算法中的错误跳过。
您的错误诊断选项?

不过,我自己已经解决了这个问题。但在我弄懂别人的代码之前,错误是被跳过的。如果 MT 方面进行了归零,错误就不会出现。

一般来说,支持和反对的意见都有。开发人员将决定哪种方法更好/更符合逻辑。

PS.如果压缩文件长度为 0,可以添加 -1 表示压缩错误。
 
Forester #:

在我的案例中,大约有 5 个被剪切的文件,它们的结尾与预期的文件结尾一样,无法再以任何方式进行检查--也就是说,这不是错误诊断,而是工作算法中的跳错。

您有哪些错误诊断方案?

不过,我自己已经解决了这个问题。但在我弄明白别人的代码之前,错误是被跳过的。如果 MT 方面进行了重置,这些错误就不会出现。

我不明白错误怎么会被跳过。函数返回的数据不为零,而且数组被填满,存档数据部分丢失?那么这是 MQL5 中的一个错误 - 应该在那里纠正。

是否检查了 _LastError 标志?

不应该设置 "预计文件结束",因为归档是一个通用的事情 - 我们可能不知道接收文件的格式。

 
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,就不会启动元素循环,所以在我看来,将数组清零是一个很好的解决方案。