Java配置文件加载及读写

来源:互联网 发布:oracle.sql.rowid 编辑:程序博客网 时间:2024/06/11 15:53

引言

我们一般是通过class.getResources(name)等通过类加载器查找资源的方法来加载程序中的配置文件。这两天在测试的过程中,发现该操作只能对classpath下的配置文件进行读写,而操作不到src源码目录下的配置文件。然后我就困惑了!非classpath路径下的文件就不能通过相对路径读写??必须指定绝对路径才能改源码里的配置文件??哇那我怎么打包源码给别人运行?难道只能给jar包咩?很懵逼啊!
对!然后我就去做功课了,最后证明果然是我傻啦~

这里写图片描述

获取src源码目录下的配置文件

当然想拿到源码路径也不是不可能的,通过System.getProperty(“user.dir”)可以获取到当前用户的项目目录,然后据此拼出绝对路径就行啦~

代码示例:

Properties bank = new Properties();String path = System.getProperty("user.dir") + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "Bank.properties";//E:/Workspace/bank/src/main/resources/Bank.propertiesbank.load(new FileInputStream(path));//直接用文件流读取配置文件

代码说明:

1.这里的System.props是System类初始化的一个系统属性集合,其中包含

键 相关值的描述 java.version Java 运行时环境版本 java.vendor Java 运行时环境供应商 java.vendor.url Java 供应商的 URL java.home Java 安装目录 java.vm.specification.version Java 虚拟机规范版本 java.vm.specification.vendor Java 虚拟机规范供应商 java.vm.specification.name Java 虚拟机规范名称 java.vm.version Java 虚拟机实现版本 java.vm.vendor Java 虚拟机实现供应商 java.vm.name Java 虚拟机实现名称 java.specification.version Java 运行时环境规范版本 java.specification.vendor Java 运行时环境规范供应商 java.specification.name Java 运行时环境规范名称 java.class.version Java 类格式版本号 java.class.path Java 类路径 java.library.path 加载库时搜索的路径列表 java.io.tmpdir 默认的临时文件路径 java.compiler 要使用的 JIT 编译器的名称 java.ext.dirs 一个或多个扩展目录的路径 os.name 操作系统的名称 os.arch 操作系统的架构 os.version 操作系统的版本 file.separator 文件分隔符(在 UNIX 系统中是“/”) path.separator 路径分隔符(在 UNIX 系统中是“:”) line.separator 行分隔符(在 UNIX 系统中是“/n”) user.name 用户的账户名称 user.home 用户的主目录 user.dir 用户的当前工作目录

2.注意拼写全路径时要用File.separator,不能偷懒用\\或是/

在windows中的文件分隔符是 \ 和 /都可以,但是在Linux中,文件分隔符只能是/,所以用了\\的程序在Linux下会出问题。
而File.separator是系统默认的文件分割符号,屏蔽了这些系统的区别,保证了在任何系统下不会出错。

3.前面说了类加载器只能拿到classpath目录下的资源,所以不能用getClass().getResourceAsStream(name)拿到文件流,而且我们已经拼出绝对路径啦,所以直接new一个文件流!

4.//TODO web应用程序中资源的寻址应该通过ServletContext.getRealPath(“/”)拿到Web应用程序的根目录的绝对路径,而不能用System.getProperty(“user.dir”)取。这个我还没有测试过。。。。

获取classpath路径下的配置文件

通过class.getResources(name)等方法获取。通过类加载器只能取得classpath下的配置文件,故在classpath路径下找不到该名称的配置文件时,会直接抛出NPE,而不会到src目录下去找文件加载。
这个能用的方法就很多啦,下面列举一下

代码示例:

getClass().getResource("/Bank.properties");//1.class.getResource("/")是从classpath根路径起查找指定name的配置文件,path参数为配置文件相对根目录的路径getClass().getResource("../Bank.properties");//2.class.getResource("")是从当前类的路径起查找指定name的配置文件,path参数为配置文件相对当前类的路径(这里假设当前类在class目录下)getClass().getClassLoader().getResourceAsStream("Bank.properties");//3.class.getResource("/") == class.getClassLoader().getResource("");ClassLoader.getSystemResourceAsStream("Bank.properties");//4.Thread.currentThread().getContextClassLoader().getResource("");//5.

代码说明:

  1. class.getResource内部都是调用classLoader.getResource,只不过通过类获取资源的方法里有一个resolveName的操作,并且当前类的classloader为null的时候,从system classloader中去加载资源。path的设置更灵活,可取当前类的相对路径
  2. . getSystemResource此方法为静态方法,可直接通过ClassLoader类名调用,是通过系统类加载器来加载配置文件的。在将j2se环境下,通过此方法可能会找不到配置文件。比如在tomcat中,系统启动类装载是通过 tomcat中一个叫WebappClassLoader的类加载来做的,而此时 SystemClassLoader是jvm的ClassLoader,所以取不到我们想要的WebappClassLoader所在的classpath下的配置文件
  3. Thread.currentThread().getContextClassLoader().getResource,此方法获取加载当前线程的ClassLoader来加载配置文件。WEB程序里的jar、resources都是由Tomcat内部来加载的,所以在代码中动态加载jar、资源文件的时候,应该是使用该方法加载资源,如果直接使用class.getClassLoader(),可能会导致和当前线程所运行的类加载器不一致(因为Java天生的多线程)。
  4. ClassLoader提供了两个方法用于从装载的类路径中取得资源:
    public URL getResource(String name);//返回一个URL资源定位, 后通过自己的方法来读取这些资源.
    public InputStream getResourceAsStream(String name);//方便获取输入流
    //getResourceAsStream(name)基本等价于getResource(name).openStream(),只不过内部封装了一个URL判空操作
  5. URI与URL:
    URI是统一资源标识符,是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。URI由包括确定语法和相关协议的方案所定义。由是三个组成部分:访问资源的命名机制、存放资源的主机名、资源自身的名称,由路径表示。例:file://a:1234/b/c/d.txt代表获取资源使用ftp协议,资源目标是a主机的1234端口的b目录下的c目录下的d.txt。
    URL是统一资源定位,是URI的特例(还有URN也是一种URI)。URL的前缀/协议,必须是Java熟悉的。URL可以打开资源,而URI则不行。
    URL和URI对象可以互相转换,使用各自的toURI(),toURL()方法即可!

大神对该问题的理解:

配置文件我们一般都是通过手动设置然后通过程序去读取得吧。如果你想动态去改变配置并且报保存数据,开发阶段都是会把这类文件和我们项目本身分隔开来的,通过绝对路径读取,就像是你上传一个文件不可能会保存在编译得那个目录,不然你得源程序重新编译那个文件就会没了。现在你的源程序就是相当于目前得项目,如果你得代码不改变,运行起来,配置文件确实能够写入然后读取呀。程序动态运行过程中写入得东西如果你想永久保存,那我们应该想办法存进数据库或者本地文件中,这样即使项目改变了但是之前得数据还是在的吧。

小白对该问题的猜想:

src目录下的配置文件应该是在编译时加载到classpath目录下,并经测试检验,在classpath目录下没有src目录下的对应配置文件时运行系统,并不会重新将配置文件加载进classpath目录下,只有在src目录下的配置文件变化时,才会重新加载进classpath目录下

原创粉丝点击