Java 使用FileInputStream在资源中加载文件
我知道在参考资料中打开文件的安全方法是:Java 使用FileInputStream在资源中加载文件,java,jar,weka,Java,Jar,Weka,我知道在参考资料中打开文件的安全方法是: InputStream is = this.getClass().getResourceAsStream("/path/in/jar/file.name"); 现在的问题是,我的文件是Weka包装包和 只有一种方法: public void load(File file) throws Exception load获取文件并将其作为FileInputStream打开。你看到解决办法了吗?我真的会 我想把模型放到参考资料里。我想创建一个临
InputStream is = this.getClass().getResourceAsStream("/path/in/jar/file.name");
现在的问题是,我的文件是Weka包装包和
只有一种方法:
public void load(File file) throws Exception
load获取文件并将其作为FileInputStream打开。你看到解决办法了吗?我真的会
我想把模型放到参考资料里。我想创建一个临时文件,将模型的内容写入临时文件,然后将临时文件传递给Weka,但它太脏了。。
其他选择 我看到了两种解决方案:
解决方案1
将类路径ressource读取到临时文件,并在调用load(file)
解决方案2
如果加载资源的类加载器是URLClassLoader,则可以尝试查找绝对文件名。但是,只有当您想要的资源作为文件系统上的文件存在时,才起作用。如果文件包含在jar中,则无法工作
ClassLoader classLoader = this.getClass().getClassLoader();
if(classLoader instanceof URLClassLoader){
URLClassLoader urlClassLoader = URLClassLoader.class.cast(classLoader);
URL resourceUrl = urlClassLoader.findResource("file.name");
if("file".equals(resourceUrl.getProtocol())){
URI uri = resourceUrl.toURI();
File file = new File(uri);
decider.load(file);
}
}
我建议编写一个实用程序类,尝试通过类加载器找到绝对文件,或者如果无法通过这种方式找到绝对文件,则使用临时文件方法作为后备方法
或者以更面向对象的方式:
public class FileResourceTest {
public static void main(String[] args) throws IOException {
File resourceAsFile = getResourceAsFile("file.name");
System.out.println(resourceAsFile);
}
private static File getResourceAsFile(String resource) throws IOException {
ClassLoader cl = FileResourceTest.class.getClassLoader();
File file = null;
FileResource fileResource = new URLClassLoaderFileResource(cl, resource);
try {
file = fileResource.getFile();
} catch (IOException e) {
fileResource = new ClasspathResourceFileResource(cl, resource);
file = fileResource.getFile();
}
return file;
}
public static interface FileResource {
public File getFile() throws IOException;
}
public static class ClasspathResourceFileResource implements FileResource {
private ClassLoader cl;
private String resource;
public ClasspathResourceFileResource(ClassLoader cl, String resource) {
this.cl = cl;
this.resource = resource;
}
public File getFile() throws IOException {
InputStream cpResource = cl.getResourceAsStream(resource);
File tmpFile = File.createTempFile("file", "temp");
FileUtils.copyInputStreamToFile(cpResource, tmpFile);
tmpFile.deleteOnExit();
return tmpFile;
}
}
public static class URLClassLoaderFileResource implements FileResource {
private ClassLoader cl;
private String resource;
public URLClassLoaderFileResource(ClassLoader cl, String resourcePath) {
this.cl = cl;
this.resource = resourcePath;
}
public File getFile() throws IOException {
File resourceFile = null;
if (cl instanceof URLClassLoader) {
URLClassLoader urlClassLoader = URLClassLoader.class.cast(cl);
URL resourceUrl = urlClassLoader.findResource(resource);
if ("file".equals(resourceUrl.getProtocol())) {
try {
URI uri = resourceUrl.toURI();
resourceFile = new File(uri);
} catch (URISyntaxException e) {
IOException ioException = new IOException(
"Unable to get file through class loader: "
+ cl);
ioException.initCause(e);
throw ioException;
}
}
}
if (resourceFile == null) {
throw new IOException(
"Unable to get file through class loader: " + cl);
}
return resourceFile;
}
}
}
您还可以使用第三方库,如,它允许您引用jar中的文件。例如,jar://arch文件uri[!绝对路径]
。由于commons vfs指定了一个表示文件的own,因此您仍然必须将内容复制到本地java.io.file
以适应Decider.load(file)
API
编辑
这很有帮助!在较新版本的java中是否有支持此要求的内容 即使我没有查看每个更新版本的每个类,我也会说不,因为类路径资源并不总是一个文件。例如,它可以是jar中的文件,甚至可以是远程资源。想想java程序员很久以前使用的小程序。因此,类路径及其资源的概念并不局限于本地系统。这显然是一件好事,因为您可以从几乎每个URL加载类,这使它更加灵活。但这种灵活性还意味着,如果需要
文件
,则必须读取资源并创建副本
但也许我上面展示的一些实用程序代码会进入JRE。也许它已经在那里了。如果是,请发表评论并让我们都知道。检查此项目,解决资源文件夹扫描:这非常有用!在较新版本的java中是否有支持此要求的内容?
public class FileResourceTest {
public static void main(String[] args) throws IOException {
File resourceAsFile = getResourceAsFile("file.name");
System.out.println(resourceAsFile);
}
private static File getResourceAsFile(String resource) throws IOException {
ClassLoader cl = FileResourceTest.class.getClassLoader();
File file = null;
FileResource fileResource = new URLClassLoaderFileResource(cl, resource);
try {
file = fileResource.getFile();
} catch (IOException e) {
fileResource = new ClasspathResourceFileResource(cl, resource);
file = fileResource.getFile();
}
return file;
}
public static interface FileResource {
public File getFile() throws IOException;
}
public static class ClasspathResourceFileResource implements FileResource {
private ClassLoader cl;
private String resource;
public ClasspathResourceFileResource(ClassLoader cl, String resource) {
this.cl = cl;
this.resource = resource;
}
public File getFile() throws IOException {
InputStream cpResource = cl.getResourceAsStream(resource);
File tmpFile = File.createTempFile("file", "temp");
FileUtils.copyInputStreamToFile(cpResource, tmpFile);
tmpFile.deleteOnExit();
return tmpFile;
}
}
public static class URLClassLoaderFileResource implements FileResource {
private ClassLoader cl;
private String resource;
public URLClassLoaderFileResource(ClassLoader cl, String resourcePath) {
this.cl = cl;
this.resource = resourcePath;
}
public File getFile() throws IOException {
File resourceFile = null;
if (cl instanceof URLClassLoader) {
URLClassLoader urlClassLoader = URLClassLoader.class.cast(cl);
URL resourceUrl = urlClassLoader.findResource(resource);
if ("file".equals(resourceUrl.getProtocol())) {
try {
URI uri = resourceUrl.toURI();
resourceFile = new File(uri);
} catch (URISyntaxException e) {
IOException ioException = new IOException(
"Unable to get file through class loader: "
+ cl);
ioException.initCause(e);
throw ioException;
}
}
}
if (resourceFile == null) {
throw new IOException(
"Unable to get file through class loader: " + cl);
}
return resourceFile;
}
}
}