如何将类路径资源加载到字节数组?
Posted
技术标签:
【中文标题】如何将类路径资源加载到字节数组?【英文标题】: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 你只是阻止我在这种情况下做一些愚蠢的事情,谢谢。
作为(替代)答案输入。 ;)
【参考方案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())
,因为它有点短。以上是关于如何将类路径资源加载到字节数组?的主要内容,如果未能解决你的问题,请参考以下文章