jar MANIFEST.MF 最大行长度 72 是否包括 EOL 字节

Does the jar MANIFEST.MF max line length of 72 include the EOL bytes

我对 Manifest specification 的理解对于 的确切定义有点模糊。特别是读

的部分

No line may be longer than 72 bytes (not characters), in its UTF8-encoded form.

我不确定 在这方面是否包含 EOL (CR LF | LF | CR) 字符。

我有两个编写清单的库的第三方实现,一个生成的内容似乎包含 EOL 字符作为行的一部分,而另一个则不包含。

虽然这并没有严格回答规范在说 line 时意味着什么的问题,但它确实根据 JDK 的实现方式回答了这个问题它围绕该规范的清单支持。你希望他们都来自同一个团队,因此规范中的任何歧义都可以通过实现的细节来澄清,但我暂时不接受它,以防找到更规范的答案。

通过阅读 JDK 源代码和 运行 一些使用 JDK 清单 class 写出清单文件的测试,我可以说 JDK(在 1.7 版)写出清单条目,其中 行长度包括 EOL 字节

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.jar.Attributes.Name.MANIFEST_VERSION;

public class ManifestTest {
  public static void main(String[] args) throws IOException {
    Manifest m = new Manifest();
    Attributes a = m.getMainAttributes();
    a.put(MANIFEST_VERSION, "1.0"); // required or the file doesn't get written

    // Long-Property: This line has 72 characters without eol, it's hard to get
    a.putValue("Line-Property", "This line has 72 characters without eol, it's hard to get");
    // Long-Property: This line has 72 characters with eol, it is hard to get
    a.putValue("Long-Property", "This line has 72 characters with eol, it is hard to get");
    a.putValue("Massive-Property", "This line wraps around always as it has a lot of characters in it");

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    m.write(out);
    System.out.println(new String(out.toByteArray(), UTF_8));
  }
}

结果如下输出

Manifest-Version: 1.0
Long-Property: This line has 72 characters with eol, it is hard to get
Massive-Property: This line wraps around always as it has a lot of cha
 racters in it
Line-Property: This line has 72 characters without eol, it's hard to g
 et

请注意,Long-Property 适合一行,因为行内容为 70 个字符 + 2 个字符的 EOL,即 <= 72。具有 72 个字符的行内容的 Line-Property 被拆分分为两行,其中第一行包含前 70 个字符 + CR LF 后跟 space 和剩余的 2 个字符。

这里值得注意的是 Manifest 读取方法对行的长度很宽松,只要行不超过 512 字节长(包括 EOL 标记),它就会愉快地读取文件如下代码所示

Manifest m = new Manifest();
String longManifest = "Manifest-Version: 1.0\r\n" +
    "Too-Long: This line is longer than 72 characters, does the Manifest class correctly \r\n" +
    " handle parsing of it even over multiple lines?\r\n";
m.read(new ByteArrayInputStream(longManifest.getBytes(UTF_8)));
System.out.println(m.getMainAttributes().getValue("Too-Long"));

这很高兴将 This line is longer than 72 characters, does the Manifest class correctly handle parsing of it even over multiple lines? 作为单个清单值输出。