检测java.lang.Class.getResourceAsStream()打开的目录
假设类路径中有以下资源:检测java.lang.Class.getResourceAsStream()打开的目录,java,io,Java,Io,假设类路径中有以下资源: /res/image/logo.png /res/image/splash.png 然后,可以使用以下方法获取logo.png的InputStream: SomeClass.class.getResourceAsStream("/res/image/logo.png"); 如果请求的资源不存在,getResourceAsStream()将返回null 但是,如果您请求的资源实际上是一个目录,则不会得到null或异常:您实际上会得到一个java.io.ByteArra
/res/image/logo.png
/res/image/splash.png
然后,可以使用以下方法获取logo.png的InputStream
:
SomeClass.class.getResourceAsStream("/res/image/logo.png");
如果请求的资源不存在,getResourceAsStream()
将返回null
但是,如果您请求的资源实际上是一个目录,则不会得到null或异常:您实际上会得到一个java.io.ByteArrayInputStream
。从这个流中转储字节后,它似乎是该目录中的资源列表(每行一个)
因此:
给出一个ByteArrayInputStream
,转储时包含:
logo.png
splash.png
是否有可靠的方法来确定由getResourceAsStream()
打开的资源实际上是一个目录?或者以其他方式访问类路径资源,这样就可以了?(也许可以通过某种方式使用getResource()
完成吗?)
更新:
出于兴趣,我调用了getResource()
,并转储了一个“资源”的URL,而我知道该“资源”在磁盘上并不作为文件存在(在本例中为/java/util/List.class
)。以下是我得到的:
jar:file:/C:/projects/<my_proj>/env/jdk/jre/lib/rt.jar!/java/util/List.class
因此,如果资源的URL不是“文件:”资源,则可以将null
视为(公认是间接的,也许不可靠)指示“资源”是目录。如果是建议的解决方案,则可以使用文件。isDirectory()
我想这个黑客会有用的。我不确定我是否会在真正的代码中使用它!;-) 据我所知,getResourceAsStream没有办法,但您可以随时通过使用
getResource
获取URL来检查它是否是文件或目录,然后获取路径,然后新建文件(路径)。isDirectory()
和新建文件(路径)。isFile()
getResource()提供URL。检查该URL,如果它以“file://”开头,则可以提取文件名,并调用newfile(name).isDirectory()
如果它不是以“file://”开头,则它位于web服务器后面,并且没有标准的方法来确定资源是否是目录
附录
尝试将“/”或“/…”添加到URL中-如果表示的资源存在,则URL引用目录。您可以执行以下操作:
URL resource = getClass().getResource("/res/image");
File folder = new File(new URI(resource.getPath()).getPath());
if(folder.isDirectory()) {
// do something
}
测试
getResource()
的非null
结果作为目录非常简单:只需检查它是否以“/”
(斜杠)结尾
如果您不信任这个简单的检查,那么您必须对每个协议分别执行检查。对于文件:
URL,有一种安全的方法:
URL url = Foo.class.getResource(".");
if(url.getProtocol().equals("file"))
{
boolean dir=new File(url.toURI()).isDirectory();
}
对其他人来说,这并不明显。有些协议甚至可能没有目录的概念(或者文件和目录之间的区别)。对于
JAR
文件,您通常会得到null
,因为JAR
文件通常不包含目录项。您可以通过类检测InputStream
是文件还是目录。如果它是一个文件,它将是一个“BufferedInputStream”,目录将是一个“ByteArrayInputStream”
例如:
InputStream is = SomeClass.class.getResourceAsStream("/res/image");
boolean isDirectory = isDirectory(is); //true
这是一个有趣的问题,但你是否有一个实际应用的想法,或者只是学术兴趣?是的,我有一个实际应用(和一些失败的单元测试)。我定义了一个(最小的)
Store
接口,它隐藏了各种类型的“文件系统”。例如,在我们的在线帮助系统中,我想为帮助servlet提供一个帮助文件存储。它不应该关心存储是文件目录、zip/jar文件还是类路径上资源的子集。我有一套单元测试来检查我编写的四个实现的行为是否相同。一个测试断言您无法打开存储中的目录,但对于基于资源的实现来说,这失败了。您看过Spring的资源和扫描支持吗?我不知道您的用例的细节,但它可能已经具备了您需要的功能。不知道它在我的applications.jar文件中,或者在我的应用程序的类路径中的某个其他.jar文件中。
URL url = Foo.class.getResource(".");
if(url.getProtocol().equals("file"))
{
boolean dir=new File(url.toURI()).isDirectory();
}
public boolean isDirectory(InputStream is) {
return is.getClass().getSimpleName().equals("ByteArrayInputStream");
}
public boolean isFile(InputStream is) {
return is.getClass().getSimpleName().equals("BufferedInputStream");
}
InputStream is = SomeClass.class.getResourceAsStream("/res/image");
boolean isDirectory = isDirectory(is); //true