我为此搜索了很长一段时间,但所有结果都指向了Java 7之前的NIO解决方案。我已经使用NIO stuff从文件系统中的特定位置读取文件,并且比以前更容易(Files.readAllBytes(path)
)。现在,我想读取一个打包在WAR和类路径中的文件。我们目前使用类似于以下代码执行此操作:
Input inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
/* iterate through the input stream to get all the bytes (no way to reliably find the size of the
* file behind the inputStream (see http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#available()))
*/
int byteInt = -1;
try
{
byteInt = inputStream.read();
while (byteInt != -1)
{
byteStream.write(byteInt);
byteInt = inputStream.read();
}
byteArray = byteStream.toByteArray();
inputStream.close();
return byteArray;
}
catch (IOException e)
{
//...
}
虽然这有效,但我希望有一个更简单/更好的方法来使用Java 7中的NIO。我猜我需要获得一个表示此路径的Path对象类路径,但我不知道该怎么做。
如果这是一件非常容易的事,我道歉。我只是想不出来。谢谢你的帮助。
答案 0 :(得分:27)
这对我有用。
import java.nio.file.Files;
import java.nio.file.Paths;
// fileName: foo.txt which lives under src/main/resources
public String readFileFromClasspath(final String fileName) throws IOException, URISyntaxException {
return new String(Files.readAllBytes(
Paths.get(getClass().getClassLoader()
.getResource(fileName)
.toURI())));
}
答案 1 :(得分:7)
Path表示文件系统上的文件。从类路径中读取资源没有帮助。您正在寻找的是一个辅助方法,它从流中读取所有内容(比您正在进行的操作更有效)并将其写入字节数组。 Apache commons-io或Guava可以帮助您。比如Guava:
byte[] array =
ByteStreams.toByteArray(this.getClass().getClassLoader().getResourceAsStream(resourceName));
如果您不想仅仅为了依赖项添加Guava或commons-io,您可以随时阅读它们的源代码并将其复制到您自己的帮助方法中。
答案 2 :(得分:2)
据我了解,您想要的是为您的资源打开ReadableByteChannel
,以便您可以使用NIO进行阅读。
这应该是一个好的开始,
// Opens a resource from the current class' defining class loader
InputStream istream = getClass().getResourceAsStream("/filename.txt");
// Create a NIO ReadableByteChannel from the stream
ReadableByteChannel channel = java.nio.channels.Channels.newChannel(istream);
答案 3 :(得分:1)
你应该看看ClassLoader.getResource()
。这将返回表示资源的URL。如果它是文件系统的本地,则它将是file://
URL。此时你可以剥离方案等,然后你就拥有了你可以做任何你想做的文件名。
但是,如果它不是file://路径,那么您可以回退到正常的InputStream。