浏览 6919 次
锁定老帖子 主题:FileUtil:获取jar所在目录
精华帖 (0) :: 良好帖 (0) :: 新手帖 (3) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-14
最后修改:2009-12-14
最近做一个企业应用,需要在项目打包后,生成的jar包所在目录生成一个临时目录。 开始,直接取了user.dir,可打包后发现出不对:user.dir为用户工作目录。 那么只能从class loading入手了,从加载资源class计算URL得到一个该目录(这样能得到结果,就是不知道有什么风险?我在windows和linux上测试过)。 我的FileUtil代码如下: public class FileUtil { private static final Log logger = LogFactory.getLog(FileUtil.class); /** * syslog应用程序被打包成为jar包发布。在syslog服务中,需要在jar文件位置创建临时文件夹,以保存数据。 * 临时文件夹:1 读文件中,ftp到中央日志服务的文件,被放到临时文件夹后再读。 * 2 分析会后的日志,保存一个月。如果选择了备份,则把每天需要备份的文件移动到一个临时备份文件夹。 * 逻辑:如果getDirFromClassLoader()方法计算不出来path,就取System.getProperty("user.dir")用户工作目录 * */ public static String getJarDir(){ String path = getDirFromClassLoader(); if(path == null){ path = System.getProperty("user.dir"); } return path; } /** * 从通过Class Loading计算路径: * 1 class文件通过jar包加载: * 如果为jar包,该包为d:/test/myProj.jar * 该方法返回d:/test这个目录(不受用户工作目录影响) * 提示:在jar包加载 的时候,通过指定加载FileUtil的class资源得到jar:<url>!/{entry}计算出加载路径 * 2 class文件直接被加载: * 如果是web工程,class文件放在D:\tools\apache-tomcat-5.5.27\webapps\webProj\WEB-INF\classes * 该方法返回D:\tools\apache-tomcat-5.5.27\webapps\webProj\WEB-INF * 即返回放class文件夹的上一层目录。 * */ private static String getDirFromClassLoader(){ try { String path = FileUtil.class.getName().replace(".", "/"); path ="/"+path+".class"; URL url=FileUtil.class.getResource(path); String jarUrl= url.getPath(); if(jarUrl.startsWith("file:")){ if(jarUrl.length()>5){ jarUrl = jarUrl.substring(5); } jarUrl = jarUrl.split("!")[0]; }else{ jarUrl = FileUtil.class.getResource("/").toString().substring(5); } File file = new File(jarUrl); return file.getParent(); } catch (Exception e) { } return null; } /** * 找出指定目录及其子目录下,满足指定后缀的文件的绝对路径。 * 提示:方法中出现异常被内部捕获。 * @param dir 指定目录 * @param suffix 文件名后缀 * * @throws IllegalArgumentException * */ public static List<String> find(String dir,String suffix){ List<String> list = new ArrayList<String>(); try { File file = new File(dir); if(file.exists() && file.isDirectory()){ find(file, suffix, list); }else{ throw new IllegalArgumentException("param \"dir\" must be an existing directory .dir = "+dir); } } catch (Exception e) { logger.error("gcw:find(dir,suffix) - "+e.getMessage()); } return list; } /** * 递归遍历,查找满足后缀的文件 * @param dirFile 必须为一个存在的目录.不能为null * @param suffix * @param list 递归遍历目录记录满足后缀的文件的绝对路径。 * */ private static void find(File dirFile,String suffix,List<String> list){ if(dirFile.exists() && dirFile.isDirectory()){ File[] subFiles = dirFile.listFiles(); for(File subFile : subFiles) { if(subFile.isDirectory()){ find(subFile, suffix, list); }else{ String path = subFile.getAbsolutePath(); if(path.endsWith(suffix)){ list.add(path); } } } }else{ throw new IllegalArgumentException("param \"dir\" must be an existing directory .dir = "+dirFile.getAbsolutePath()); } } }
jar中加载资源不熟悉的,可以看看javaee的这个讨论:主题:深入jar包:从jar包中读取资源文件 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-12-14
最后修改:2009-12-14
这位大哥,您有没有试过如果什么路径都不指定,默认是在那个目录呢?
hahaha |
|
返回顶楼 | |
发表时间:2009-12-15
vlinux 写道 这位大哥,您有没有试过如果什么路径都不指定,默认是在那个目录呢?
hahaha 你的class放在什么文件夹呢,就在那个目录。如果没有发生小概率事件,基本上不去取user.dir。 对于你的问题真么有看明白。 |
|
返回顶楼 | |
发表时间:2009-12-15
认真执行了一遍代码,发现还真是我理解错了。
好奇怪的需求,什么情况下需要这样呢?下次我碰到了也会用你这样的方法解决了 |
|
返回顶楼 | |
发表时间:2009-12-15
clazz.getProtectionDomain().getCodeSource().getLocation()
|
|
返回顶楼 | |
发表时间:2009-12-15
LZ就别重复造轮子了...
|
|
返回顶楼 | |
发表时间:2009-12-15
支持楼主造出一个热气腾腾的轮子!
|
|
返回顶楼 | |
发表时间:2009-12-15
最后修改:2009-12-15
您之前试过
new File("").getAbsolutePath()吗? |
|
返回顶楼 | |
发表时间:2009-12-15
理论上用class.getProtectionDomain().getCodeSource().getLocation().getFile();比较准.
不过有两个需要注意的: 1.返回如果是个文件说明是Jar包形式,返回的是jar,如果是目录说明是class,返回的是class所在的目录. 2.如果加载class的classLoder是一个自定义,那个这个方法很可能不支持,因为自定义的classLoder可能没有完成这部分功能. |
|
返回顶楼 | |
发表时间:2009-12-15
mxswl 写道 clazz.getProtectionDomain().getCodeSource().getLocation()
谢谢mxswl的提示! 这样拿到的URL直接可以getFile或者getPath得到文件系统的路径。我的做法太繁琐了。有时间在研究研究security 包。 关于new File("")与user.dir类似。 |
|
返回顶楼 | |