【问题标题】:Java: Reading from getResourceAsStream gets too many bytesJava:从 getResourceAsStream 读取得到太多字节
【发布时间】:2022-01-24 03:10:13
【问题描述】:

我正在尝试使用 getResourceAsStream 读取二进制文件。问题是我得到了太多字节。根据 ls,该文件长 56374 字节,但是当我在代码中读取它时,我始终得到 85194 字节。

InputStream fileData = checkNotNull(MyClass.class.getResourceAsStream(path));
byte [] b = IOUtils.toByteArray(fileData);
int count = b.length;

我用类似的代码得到相同的结果:

InputStream fileData = checkNotNull(MyClass.class.getResourceAsStream(path));
byte [] b = new byte[1000*1000];
int count  = fileData.read(b);

如果我在没有资源的情况下运行代码,一切都很好,我得到了正确的字节数。

    FileInputStream fis = new FileInputStream(path);
    byte [] b = new byte[1000*1000];
    int count  = fis.read(b);

我读取的数据的第一个字节匹配。检查输出,第一个不匹配的字节是“CO”,输出为“ef bf bd”。

也许它试图以某种方式与 UTF-8 进行转换?这里的一切都应该是二进制的。不涉及文本。

任何帮助表示赞赏。

编辑:我很确定我正在阅读正确的文件。如果我重命名文件,则读取失败。改回来,就可以了。我在intellij中更改了资源名称,它在代码中重构并更改了名称,仍然有效。

Edit2:我错了。我没有查看正确的文件。我追踪到 getResourceAsStream。我们的构建系统将文件复制到构建输出目录,然后从那里运行。这个目标文件的大小错误,所以看起来副本正在造成一些损害。

请注意,每当我更改名称时,它都会再次复制文件,这就是为什么我认为我有正确的文件。

【问题讨论】:

    标签: java utf-8 classloader


    【解决方案1】:

    我怀疑当您将文件作为资源读取时,您实际上正在读取文件的不同版本。 JVM 读取由类加载器定位的资源。因此,当您将相同的 path 字符串解析为资源和文件时,它们很有可能解析为不同的东西。

    我怀疑根本问题是 Unicode 还是 UTF-8。您的示例表明您正在使用InputStream 读取状态。这种方法是编码不可知的......并将为您提供文件中的原始字节。普通的InputStream 不会尝试解码它读取的字节。

    话虽如此,您正在读取的字节不同是绝对重要的。但这与简单地读取不同的文件是一致的。

    【讨论】:

    • 我没有理由支持 unicode 假设。它不应该参与。 “CO”应转换为 utf-8 中的“c3 80”,而不是“ef bf bd”。我只是想想想当它看到一个高位集时会扩展到更多字符。
    • 另外,我编辑了问题以澄清我确定我有正确的文件。
    • 好吧......如果你的代码真的读取同一个文件并重复地得到不同的结果,那么这可能是由于某种类加载器的疯狂;即,您正在使用自定义类加载器,该类加载器在您读取资源流时会破坏数据。无论哪种方式,您都需要提供minimal reproducible example
    • 不。你是对的。请参阅有问题的edit2。
    猜你喜欢
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    相关资源
    最近更新 更多