专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 行业应用

告辞获取不安全的相对路径-取当前类的Classpath(转)

发布时间:2010-06-06 18:53:48 文章来源:www.iduyao.cn 采编人员:星星草
告别获取不安全的相对路径-取当前类的Classpath(转)
1.new File(./xx.txt);或者是new File(xx.txt);

这种方法实际上是和window操作系统有关系的,对批处理和Win32编程有研究的朋友知道,运行一个程序要让操作系统知道两点,1是文件存放的所在位置,2是文件的起始位置,这个起始位置很重要的,文件可以放置在C:\,而起始位置可以是D:\

感兴趣的朋友可以试试新建立一个批处理test.bat

dir
pause
放置在c盘运行它,可以列出c盘的目录

然后在这个批处理文件上面创建一个快捷方程式,然后右键->属性->修改它的起始位置为d盘

点击这个快捷方程式再看结果,如何?列出的是d盘的目录.

所以在java中使用new File(xx.txt);是非常不安全的,因为.这个路径的到底在哪里,取决于调用java 命令的起始位置定义在哪里.

tomcat/bin 下面的catalina.bat调用了java所以在tomcat环境下"."的位置就是tomcat/bin,但是eclipse启动程序,起始位置就是eclipse的项目路径下了.不多说,大家已经可以看出来了,这不是一个好方法.因为不能通过程序所在位置来确定一个路径.

当然并不是说这种方法就不可取,熟悉命令的朋友会想到在启动java.exe的时候将%CD%传进jvm里面,这是个方法,但是未免太麻烦了些.

2.类.class.getClassLoader().getResource("");

这也算是个比较流行的方法,但是使用它获取相对路径很不明朗,因为大部分情况我们希望相对路径针对我们的class来说是固定的,如果使用此方法,这把决定权交给了类加载器,例如tomcat的类加载是非委托机制的,而weblogic的类加载是委托机制的,仅凭此一点就决定了,使用此方法不能保证在任何环境下,相对路径是真正相对于class文件的.它是不安全的,不过大部分情况下它是安全的.我也在相当长的一段时间内认为他是安全的,后来在weblogic的一个复杂类加载器环境中发现它的不安全性.

3.类.class.getResource("")

看上去这确实是个好方法,但是它的局限性在于如果类在jar中的话,那么在打jar包的时候需要将文件夹也一起打进去,否则会返回null,jar文件实际上就是zip文件,zip文件中:文件是文件,文件夹是文件夹,不是关联在一起的,很多开源的jar包就没有把目录打进去只打了classes文件,虽然你能够看到文件的目录层次结构,但是调用类.class.getResource("")会返回null的.因为文件的目录结构和文件夹本身是两回事.对于这个问题可追溯到我以前的一篇帖子http://topic.csdn.net/u/20080520/21/1dc25316-8316-46f8-904b-ded9c4b7587a.html

至于在web应用中取相对路径的方法我就不说了,因为他有局限性,我这里说的都是在任何环境下都可以使用的方法.

取相对路径最安全的的方法是什么呢?答案是取类本身在系统中存储的文件位置,然后根据包层次向上一直找到Classpath下面:实现非常简单,好了不多说了放代码:

package com.syj.util;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URL;

/**
* <p>
* Title:URL辅助工具类
* </p>
*
* <p>
* Copyright: 转载请注明出处http://blog.csdn.net/sunyujia/
* </p>
*
* @author 孙钰佳
* @mainsunyujia@yahoo.cn
* @date Sep 21, 2008 12:31:23 PM
*/
public class URLUtil {
    /**
     *
     * Description:取得当前类所在的文件
     *
     * @param clazz
     * @return
     * @mailsunyujia@yahoo.cn
     * @since:Sep 21, 2008 12:32:10 PM
     */
    public static File getClassFile(Class clazz) {
        URL path = clazz.getResource(clazz.getName().substring(
                clazz.getName().lastIndexOf(".") + 1)
                + ".class");
        if (path == null) {
            String name = clazz.getName().replaceAll("[.]", "/");
            path = clazz.getResource("/" + name + ".class");
        }
        return new File(path.getFile());
    }

    /**
     *
     * Description:同getClassFile 解决中文编码问题
     *
     * @param clazz
     * @return
     * @mailsunyujia@yahoo.cn
     * @since:Sep 21, 2008 1:10:12 PM
     */
    public static String getClassFilePath(Class clazz) {
        try {
            return java.net.URLDecoder.decode(getClassFile(clazz)
                    .getAbsolutePath(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     *
     * Description:取得当前类所在的ClassPath目录
     *
     * @param clazz
     * @return
     * @mailsunyujia@yahoo.cn
     * @since:Sep 21, 2008 12:32:27 PM
     */
    public static File getClassPathFile(Class clazz) {
        File file = getClassFile(clazz);
        for (int i = 0, count = clazz.getName().split("[.]").length; i < count; i++)
            file = file.getParentFile();
        if (file.getName().toUpperCase().endsWith(".JAR!")) {
            file = file.getParentFile();
        }
        return file;
    }

    /**
     *
     * Description: 同getClassPathFile 解决中文编码问题
     *
     * @param clazz
     * @return
     * @mailsunyujia@yahoo.cn
     * @since:Sep 21, 2008 1:10:37 PM
     */
    public static String getClassPath(Class clazz) {
        try {
            return java.net.URLDecoder.decode(getClassPathFile(clazz)
                    .getAbsolutePath(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        System.out.println(getClassFilePath(URLUtil.class));
        System.out.println(getClassPath(URLUtil.class));
    }
}



在eclipse下执行

输出为

D:\SYJ.WORK\SYJ.WORKSPACE\ws1\util\classes\com\syj\util\URLUtil.class
D:\SYJ.WORK\SYJ.WORKSPACE\ws1\util\classes
打成jar包后在桌面下执行

输出为
file:\C:\Documents and Settings\Administrator\桌面\util.jar!\com\syj\util\URLUtil.class
file:\C:\Documents and Settings\Administrator\桌面

所取得的路径一直都是class文件的classpath目录.
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

  • 《松本行弘的程序全世界》之面向对象

    《松本行弘的程序世界》之面向对象 最近读《SICP》把脑细胞搞死大半,还没看完2章,而且看得也是一知半解,实在是受不了了,...

  • GroovyHelp 3.2.7 GA公布

    GroovyHelp 3.2.7 GA发布 GroovyHelp简介   GroovyHelp是一款Javadoc及Groovydoc搜索查阅软件,它能够帮助Java开发人员以...

  • Velocity在Roller中的使用

    Velocity在Roller中的应用 Velocity是java世界中出现比较早,也比较成熟的、性能比较好的、应用也比较广泛的模板框架。   所...

  • Rpc远程调用框架的设计与兑现(2)

    Rpc远程调用框架的设计与实现(2) 接上: 3   基于Json的前后端数据交互 3.1   轻量级的数据交换形式 3.1.1    什么是Jso...

  • excel 单元格的锁定 以及 JXL的兑现方式

    excel 单元格的锁定 以及 JXL的实现方式 在使用excel表格时,有些列是不希望用户可以修改的,诸如审计日志里面确定的部分,而审计...

  • 仓秤跟散料秤:java连接opc Server

    仓秤和散料秤:java连接opc Server 这三篇都是之前写好的,一直没发。 这次一起发出来吧。   java连接硬件很痛苦,特别是对我这...

  • Rpc远程调用框架的设计与兑现(1)

    Rpc远程调用框架的设计与实现(1) Rpc远程调用框架的设计与实现 1     Rpc远程调用框架设计概述 1.1   研究背景 1.1.1...

  • 集合中的线程安全有关问题

    集合中的线程安全问题 一、why? Java中常用的集合框架推荐使用的三个实现:HashSet\ArrayList\HashMap都是线程不安全的.如...

  • Java定时任务的兑现

    Java定时任务的实现 本例依据Java自身提供的接口实现,通过监听器(Listener)和定时器(Timer)定时执行某个任务(Task)。 MyListener: ...

  • java中log日记的使用

    java中log日志的使用 一、介绍  Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控...

热门推荐: