【问题标题】:How to load a classpath resource to an array of byte?如何将类路径资源加载到字节数组?
【发布时间】:2012-06-04 11:14:19
【问题描述】:

我知道如何获取给定类路径资源的输入流,从输入流中读取直到我到达末尾,但这看起来是一个非常常见的问题,并且我想知道是否有我不知道的 API,或者可以使事情变得如此简单的库

byte[] data = ResourceUtils.getResourceAsBytes("/assets/myAsset.bin")

byte[] data = StreamUtils.readStreamToEnd(myInputStream)

例如!

【问题讨论】:

  • “这看起来是个很常见的问题” Java 方法通常会接受 InputStream
  • 认为对于 Guava,这或多或少是 Resources.toByteArray(Resources.getResource(contextClass, resourceName))?
  • @AndrewThompson 你只是阻止我在这种情况下做一些愚蠢的事情,谢谢。
  • 作为(替代)答案输入。 ;)

标签: java io inputstream embedded-resource


【解决方案1】:

虽然我同意 Andrew Thompson 的观点,但这是一个从 Java 7 开始工作并使用 NIO-API 的本机实现:

byte[] data = Files.readAllBytes(Paths.get(this.getClass().getClassLoader().getResource("/assets/myAsset.bin").toURI()));

【讨论】:

  • 如果我从 JAR 运行,则会失败并出现 FileSystemNotFoundException。我可以通过使用 FileSystems.newFileSystem 将 JAR 注册为文件系统来使其工作,但我必须为每个要从中读取资源的 JAR 执行此操作。
【解决方案2】:

Java 9 原生实现:

byte[] data = this.getClass().getClassLoader().getResourceAsStream("/assets/myAsset.bin").readAllBytes();

【讨论】:

    【解决方案3】:

    我通常使用以下两种方法将Resource转换为byte[]数组。

    1 - 接近

    您需要首先在Resource 对象上调用getInputStream(),然后将其传递给convertStreamToByteArray 方法,如下所示......

    InputStream stream = resource.getInputStream();
    long size = resource.getFile().lenght();
    
    byte[] byteArr = convertStreamToByteArray(stream, size);
    
    public byte[] convertStreamToByteArray(InputStream stream, long size) throws IOException {
    
        // check to ensure that file size is not larger than Integer.MAX_VALUE.
        if (size > Integer.MAX_VALUE) {
            return new byte[0];
        }
    
        byte[] buffer = new byte[(int)size];
        ByteArrayOutputStream os = new ByteArrayOutputStream();
    
        int line = 0;
        // read bytes from stream, and store them in buffer
        while ((line = stream.read(buffer)) != -1) {
            // Writes bytes from byte array (buffer) into output stream.
            os.write(buffer, 0, line);
        }
        stream.close();
        os.flush();
        os.close();
        return os.toByteArray();
    }
    

    2 - 接近

    正如 Konstantin V. Salikhov 建议的那样,您可以使用 org.apache.commons.io.IOUtils 并调用其 IOUtils.toByteArray(stream) static 方法并将 InputStream 对象传递给它...

    byte[] byteArr = IOUtils.toByteArray(stream);
    

    Note - 只是想我会提到这一点,toByteArray(...) 会检查以确保文件大小不大于Integer.MAX_VALUE,因此您不必检查这一点。

    【讨论】:

    • 好方法,但我认为你的意思是 convertStreamToByteArray 而不是 Steam。 :) 不错的答案。
    • @PabloRS 我已经纠正了错字。塔:)
    【解决方案4】:

    常见的 Java 方法将接受 InputStream。在大多数情况下,我建议将流直接传递给感兴趣的方法。

    许多相同的方法也将接受URL(例如,从getResource(String) 获得)。这有时会更好,因为各种方法都需要可重新定位的InputStream,而且有时从getResourceAsStream(String) 返回的流不可是可重新定位的。

    【讨论】:

      【解决方案5】:

      看看 Google guava ByteStreams.toByteArray(INPUTSTREAM),这可能就是你想要的。

      【讨论】:

        【解决方案6】:

        看看 Apache IOUtils - 它有很多处理流的方法

        【讨论】:

        • 更准确地说是IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream("XXX")
        • 这对我在 2016 年很有用。我正在使用最新版本的 IOUtils 和 Maven:https://mvnrepository.com/artifact/commons-io/commons-io/2.5,通过 @yunandtidus 的建议谢谢。
        • 我最喜欢的是IOUtils.resourceToByteArray("XXX", getClass().getClassLoader()),因为它有点短。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-25
        • 2011-03-27
        • 2018-03-29
        • 2011-04-22
        相关资源
        最近更新 更多