项目工程下读取文件的几种方式。
此时测试类与图片位置无关。
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("getTclazz.jpg");
//使用getClassLoader,不加 /
InputStream inputStream = getClass().getResourceAsStream("/getTclazz.jpg");
//这里需要加 /
① 如果测试类不在该目录下-与文件不同目录
项目完整路径:
InputStream inputStream =
getClass().getClassLoader().getResourceAsStream("com/jdbc/dao/getTclazz.jpg");
/*不要加 / , /com/jdbc/dao/getTclazz.jpg 错误!\--*/
-------------------------------------------------------
InputStream inputStream = getClass().getResourceAsStream("/com/jdbc/dao/getTclazz.jpg");
// 要加 /
② 如果测试类在该目录下-与文件同一目录
调用的java类文件在该包下,【如测试类和文件都在com.jdbc.dao包下】则可使用:
InputStream inputStream = getClass().getResourceAsStream("getTclazz.jpg");
//如果不加 / ,则相对的是该类所在的位置
1)getClass().getResourceAsStream(“getTclazz.jpg”);
2)getClass().getResourceAsStream("/com/jdbc/dao/getTclazz.jpg");
3)getClass().getClassLoader().getResourceAsStream(“com/jdbc/dao/getTclazz.jpg”);
第一种和第二种方式是采用Class对象去加载,第三种采用ClassLoader对象去加载资源文件,之所以Class对象也可以加载资源文件是因为Class类封装的ClassLoader的getResourceAsStream方法。
从Class类中的源码中可以看出:
public InputStream getResourceAsStream(String name) {
//这里有名字解析操作
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name);
}
resolveName方法源码如下:
/**
* Add a package name prefix if the name is not absolute
* Remove leading "/" if name is absolute
*/
private String resolveName(String name) {
if (name == null) {
return name;
}
if (!name.startsWith("/")) {
Class> c = this;
while (c.isArray()) {
c = c.getComponentType();
}
//这里将会获取当前测试类的包名,并将 . 替换为 /
String baseName = c.getName();
int index = baseName.lastIndexOf('.');
if (index != -1) {
name = baseName.substring(0, index).replace('.', '/')
+"/"+name;
}
} else {
name = name.substring(1);
}
return name;
}
即,如果name是绝对路径(带有/)那么就移除/然后使用classloader.getResourceAsStream(name)来获取流。
如果name是相对路径(不带有/),那么就添加包前缀,然后使用classloader.getResourceAsStream(name)来获取流。
ClassLoader.getResourceAsStream()方法如下:
//不会再次解析name
public InputStream getResourceAsStream(String name) {
URL url = getResource(name);
try {
return url != null ? url.openStream() : null;
} catch (IOException e) {
return null;
}
}
最终都会走到ClassLoader.getResource()方法:
public URL getResource(String name) {
URL url;
if (parent != null) {
url = parent.getResource(name);
} else {
// 使用该方法加载资源
url = getBootstrapResource(name);
}
if (url == null) {
url = findResource(name);
}
return url;
}
解释如下
第三种是最本质的做法,前两种也是基于第三种去实现的。JVM会使BootstrapLoader去加载资源文件。所以路径还是这种相对于类根目录。
第一种方式将给资源文件添加当前类的包名作为路径使用BootstrapLoader加载。
第二种方式资源文件拥有/
,则直接使用 / 后面的部分作为路径去加载资源文件。
如下,当文件在src根目录下时,使用三种方式读取的结果:
如果文件与测试类在同一包下,第一个方式可以读取,其他两种不可以。
相对路径:
InputStream inputStream = new FileInputStream("getTclazz.jpg");
绝对路径:
InputStream inputStream = new FileInputStream("C:\\Users\\12746\\Workspaces\\MyEclipse 8.5\\firstJDBCPro2\\getTclazz.jpg");
① 获取当前类路径
/C:/Users/12746/Workspaces/MyEclipse%208.5/Spring-2/WebRoot/WEB-INF/classes/com/web/test/
path = this.getClass().getResource("").getPath();
即,getResourceAsSteam获取的是classes中的文件(项目结构图中的src下)。
② 获取项目根路径
/* 获取工程根目录C:\Users\12746\Workspaces\MyEclipse 8.5\Spring-2 */
path = System.getProperty("user.dir");
③ 获取类加载路径
1. / 表示相对于src目录;
2. getClassLoader()只能使用相对路径
path = this.getClass().getResource("/").getPath();
/*/C:/Users/12746/Workspaces/MyEclipse%208.5/Spring-2/WebRoot/WEB-INF/classes/*/
path = this.getClass().getClassLoader().getResource("").getPath();
以上举例,文件在src或项目下,并没有在WebRoot下。如果文件在WebRoot下,请使用ServletContext获取。
这里使用的是fastJSON,源码实例如下:
/**
* 读取json文件并解析为JSONObject
* @param path--文件保存在classpath下的全路径 如test.json
*/
public static JSONObject readerJSON (String path) throws Exception {
try {
if (!path.startsWith("/")&&!path.startsWith("\\")){
path="/"+path;
}
InputStream inputStream = ReaderJSONUtil.class.getResourceAsStream(path);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuffer jsonBuffer = new StringBuffer();
String line=null;
while ((line=bufferedReader.readLine())!=null){
jsonBuffer.append(line);
log.debug(line);
}
return JSON.parseObject(jsonBuffer.toString());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}