从 ZIP 中提取的文件在重新保存之前无法识别

File extracted from ZIP not recognized until re-save

问:为什么重新保存文件与直接从 zip 文件中提取不同?特别是 Windows?

上下文

我有一个 angular 应用程序可以准备一个文本文件以导入商用机器。为了方便用户,我们提供了一个 zip 文件,以便可以向用户提供所需的文件夹结构。他们将此文件写入 USB 驱动器并使用它导入机器。

问题

如果将下载的zip文件直接解压到U盘中(获取文件和所需的文件夹结构),机器无法识别嵌入的文本文件。

疑难解答

如果我用任何文本编辑器打开文件,添加一个space,删除space,然后将文件重新保存到U盘,那么机器就会识别该文件。或者,如果我将zip解压缩到本地文件系统,然后将文件夹结构从本地文件系统复制到USB,那么机器也会识别它。

如果我切换到 Linux,那么来自 nano 的 'write out' 将修复该文件。如果我在文件上使用 touch 命令,问题仍然存在。

怀疑是 whitespace/line-ending 问题,我尝试了几种差异工具,但没有发现明显差异:

其他信息:

JS邮编:

const zip = new JSZip();
zip.folder('FolderA/FolderB/FolderC').file('FILE.TXT', new File([contentString], 'TEMP.TXT', { type: 'text/plain' }));
zip.generateAsync({ type: 'blob' })
  .then(function (content) {
    saveAs(content, 'ZipFile.ZIP');
  });

在这一点上,我没主意了。希望这里有人能对这种奇怪的行为有所了解。

TL;DR:检查文件属性(例如存档、只读、隐藏、系统等)。

我们的系统专门寻找存档位并以任何方式修改文件并设置此位。


这很难找出答案,但与我们的嵌入式系统程序员聊了一会儿后找到了答案。

我们的机器在搜索要导入的文件时专门搜索存档位(Windows 文件属性)。此位是 Windows NTFS 的遗物,几乎已过时。出于所有意图和目的,它是一个脏标志,用于指出在下一个备份 运行 中应该 archived/backed 的文件。有很多更好的方法可以做到这一点,所以它已经过时了。

但是,无论出于何种原因,我们的系统仅搜索设置了该位的文件。这就是 opening/copying/moving 该文件可以解决问题的原因,因为以任何方式更改它都会设置此存档位(脏标志)。

如果您想了解更多信息,请参阅 here and here

因此,如果您遇到类似问题,请检查这些文件属性。

我们使用的是 Microchip 的 Harmony USB 驱动程序,因此这可能是该工具的一个细微差别(或者可能只是来自在线示例之一的人工制品)。

您可以使用 Windows 资源管理器中的文件属性或 Windows 命令提示符中的 > attrib <file> 命令来查看它。


修复:

Windows:您可以使用 > attrib +a <file> 从命令提示符设置值或使用 > attrib -a <file>.[=21= 删除它]

如果在 Windows 主机上使用 node.js,您可以使用 the winattr library from NPM 来操作这些属性。

Linux: 您可以使用 $ getfattr$ setfattr 来设置位(参见 here and here)。

  • 注意:我链接的答案说使用 $ setfattr -h -v 0x00000020 -n system.ntfs_attrib_be <target-file> 但是当我尝试这样做时,我得到了一个不支持的操作。我最终使用了 java 解决方案,但是当我之后检查文件时,似乎等效的命令应该是 $ setfattr -n user.DOSATTRIB -v 0sMHgyMAA= <target-file>。你的里程可能会有所不同,但我提供它以防它对任何人有帮助。

Java: 您也可以从任何系统 use Java