在java开发中,我们经常会遇到需要获取文件路径的需求,获取文件时需要将文件的路径作为参数,如果填写绝对路径,会面临程序的可移植性不足的问题,下面给大家带来一个路径处理方法,可以有效解决文件的路径获取问题。
1:获取单个文件
在Java中,我们可以使用“四点法”获取文件路径:
Thread.currentThread().getContextClassLoader().getResource
("com/mymath/lib/Path.path").getPath();
使用这种方案,我们可以获取到在包
com.mymath.lib
下的Path.path文件的绝对路径,可以使用该路径进行IO流的创建等工作,但这并不是完整的方案。
2:使用一个固定的Path文件获取到整个包体系的路径
我们可以在一个包中创建一个路径文件,这个文件中没有任何内容,只是用来给路径定位的文件,创建一个专门的路径文件可以不影响其他文件的使用,且不用担心其他文件被删除后路径无法读取。
如图,创建一个Path.path文件,和其他程序文件一起存放
创建好文件后,就可以开始获取其他包路径下的文件了
2.1:创建Content类
/**
* 处理文件路径的常量类
*/
public final class Content {
/**
* 文件根目录
*/
public static final String ROOT_CONTENT;
/**
* 日志文件目录(这个值就是文件的具体路径包括文件名,可以直接使用)
*/
public static final String LOG_FILE_CONTENT;
/**
* 系统文件目录(这个值是目录,需要加上文件名使用)
*/
public static final String SYSTEM_FILE_CONTENT;
/**
* 函数文件目录(这个值是目录,需要加上文件名使用)
*/
public static final String FUNCTION_CLASS_CONTENT;
static{
//在这里加载路径,请见下文
}
}
在Content类中,定义了根路径,日志路径,系统文件路径等路径。使用
public static final 修饰,以常量的形式创建,这样,我们就可以在其他类中直接使用这些路径了。
2.2:加载文件路径
String path = Objects.requireNonNull(Thread.currentThread().
getContextClassLoader().
getResource("com/mymath/lib/Path.path")).getPath();
path = path.substring(0,path.length() - 13);
代码解释:第一行使用“四点法”获取路径文件的绝对路径,第二行去掉路径的文件名后缀,
得到纯净的包路径(去掉“lib/Path.path”)
通过以上两行代码,可以得到包
com.mymath
的绝对路径。得到包路径后,就可以继续初始化其他包的路径了
//日志路径
LOG_FILE_CONTENT = ROOT_CONTENT + "SystemLog.log";
//文件路径
SYSTEM_FILE_CONTENT = ROOT_CONTENT + "lib/";
//函数类路径
FUNCTION_CLASS_CONTENT = ROOT_CONTENT + "function/";
但这还有缺陷,如果绝对路径中含有中文,就会出现URL乱码造成路径无法被JVM识别
2.3:解码中文路径
我们只需要加上一行语句:
//解码中文路径
ROOT_CONTENT = URLDecoder.decode(path, StandardCharsets.UTF_8);
就可以得到中文路径。
decode方法会解码URL路径中的中文,对英文不做处理。
URLDecoder为JDK自带的类,在java.net包下,无需依赖外部框架。
这样,一个完整的路径类就编写完了,只要包名不变,路径文件保留,就可以把整个程序移植到任意位置进行使用,而无需修改源代码或重新编译。
完整代码如下:
/**
* 处理文件路径的常量类
*/
public final class Content {
/**
* 文件根目录
*/
public static final String ROOT_CONTENT;
/**
* 日志文件目录(这个值就是文件的具体路径包括文件名,可以直接使用)
*/
public static final String LOG_FILE_CONTENT;
/**
* 系统文件目录(这个值是目录,需要加上文件名使用)
*/
public static final String SYSTEM_FILE_CONTENT;
/**
* 函数文件目录(这个值是目录,需要加上文件名使用)
*/
public static final String FUNCTION_CLASS_CONTENT;
static {
String path = Objects.requireNonNull(Thread.currentThread()
.getContextClassLoader().getResource
("com/mymath/lib/Path.path")).getPath();
path = path.substring(0,path.length() - 13);
//解码中文路径
//根路径
ROOT_CONTENT = URLDecoder.decode(path, StandardCharsets.UTF_8);
//日志路径
LOG_FILE_CONTENT = ROOT_CONTENT + "SystemLog.log";
//文件路径
SYSTEM_FILE_CONTENT = ROOT_CONTENT + "lib/";
//函数类路径
FUNCTION_CLASS_CONTENT = ROOT_CONTENT + "function/";
logger.info("设置根路径为:" + ROOT_CONTENT);
logger.info("设置日志路径为:" + LOG_FILE_CONTENT);
logger.info("设置系统文件路径为:" + SYSTEM_FILE_CONTENT);
logger.info("设置函数文件路径为:" + FUNCTION_CLASS_CONTENT);
}
private Content() {
throw new IllegalAccessError("不能创建Content对象!");
}
}
只需要修改上述类中字符串的内容即可读取不同文件。