不管你是新手还是老鸟,在程序中读取资源文件总会遇到一些找不到文件的问题,这与Java底层的实现有关,不能算bug,只要方法得当,问题还是可以解决的。

项目的文件夹结构:
repathtest
├─src
│ └─com
│ └─lavasoft
│ ├─test
│ └─res
├─doc

1、在Java开发工具的project中使用相对路径
在project中,相对路径的根目录是project的根文件夹,在此就是repathtest文件夹了。
创建文件的写法是:
File f = new File("src/com/lavasoft/res/a.txt");

File f = new File("doc/b.txt");

注意:
路径不以“/”开头;
脱离了IDE环境,这个写法就是错误的,也并非每个IDE都如此,但我见到的都是这样的。

2、通过CLASSPATH读取包内文件
读取包内文件,使用的路径一定是相对的classpath路径,比如a,位于包内,此时可以创建读取a的字节流:
InputStream in = ReadFile.class.getResourceAsStream("/com/lavasoft/res/a.txt");
有了字节流,就能读取到文件内容了。

注意:
这里必须以“/”开头;

3、看看完整的测试代码
package com.lavasoft.test;

import java.io.*;

/**
* Java读取相对路径的文件
*
* @author leizhimin 2010-1-15 10:59:43
*/
public class ReadFile {
public static void main(String[] args) {
readTextA_ByClassPath();
readTextA_ByProjectRelativePath();
readTextB_ByProjectRelativePath();
}

/**
* 通过工程相对路径读取(包内)文件,注意不以“/”开头
*/
public static void readTextA_ByProjectRelativePath() {
System.out.println("-----------------readTextA_ByProjectRelativePath---------------------");
File f = new File("src/com/lavasoft/res/a.txt");
String a = file2String(f, "GBK");
System.out.println(a);
}

/**
* 通过工程相对路径读取(包外)文件,注意不以“/”开头
*/
public static void readTextB_ByProjectRelativePath() {
System.out.println("-----------------readTextB_ByProjectRelativePath---------------------");
File f = new File("doc/b.txt");
String b = file2String(f, "GBK");
System.out.println(b);
}

/**
* 通过CLASSPATH读取包内文件,注意以“/”开头
*/
public static void readTextA_ByClassPath() {
System.out.println("-----------------readTextA_ByClassPath---------------------");
InputStream in = ReadFile.class.getResourceAsStream("/com/lavasoft/res/a.txt");
String a = stream2String(in, "GBK");
System.out.println(a);
}

/**
* 文件转换为字符串
*
* @param f 文件
* @param charset 文件的字符集
* @return 文件内容
*/
public static String file2String(File f, String charset) {
String result = null;
try {
result = stream2String(new FileInputStream(f), charset);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return result;
}

/**
* 文件转换为字符串
*
* @param in 字节流
* @param charset 文件的字符集
* @return 文件内容
*/
public static String stream2String(InputStream in, String charset) {
StringBuffer sb = new StringBuffer();
try {
Reader r = new InputStreamReader(in, charset);
int length = 0;
for (char[] c = new char[1024]; (length = r.read(c)) != -1;) {
sb.append(c, 0, length);
}
r.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
(代码写得粗糙,异常没做认真处理)

运行结果:
-----------------readTextA_ByClassPath---------------------
aaaaaaaaa
sssssssss
-----------------readTextA_ByProjectRelativePath---------------------
aaaaaaaaa
sssssssss
-----------------readTextB_ByProjectRelativePath---------------------
bbbbbbbbbbb

Process finished with exit code 0

这是通过IDEA开发工具运行的,结果没问题,如果换成控制台执行,那么使用了项目相对路径的读取方式会失败,原因是,此时已经脱离了项目的开发环境,-----这个问题常常困扰着一些菜鸟,代码在开发工具好好的,发布后执行就失败了!
下面我截个图:

5、获取CLASSPATH下文件的绝对路径
当使用相对路径写入文件时候,就需要用到绝对路径。下面是个例子:
package com.lavasoft;

import java.io.File;

/**
* CLASSPATH文件的绝对路径获取测试
*
* @author leizhimin 2010-1-18 9:33:02
*/
public class Test {
//classpath的文件路径
private static String cp = "/com/lavasoft/cfg/syscfg.properties";

public static void main(String[] args) {
//当前类的绝对路径
System.out.println(Test.class.getResource("/").getFile());
//指定CLASSPATH文件的绝对路径
System.out.println(Test.class.getResource(cp).getFile());
//指定CLASSPATH文件的绝对路径
File f = new File(Test.class.getResource(cp).getFile());
System.out.println(f.getPath());
}
}

输出:
/D:/projects/bbt/code/cdn/planrpt/out/production/planrpt/
/D:/projects/bbt/code/cdn/planrpt/out/production/planrpt/com/lavasoft/cfg/syscfg.properties
D:\projects\bbt\code\cdn\planrpt\out\production\planrpt\com\lavasoft\cfg\syscfg.properties

Process finished with exit code 0

总结
使用工程相对路径是靠不住的。
使用CLASSPATH路径是可靠的。
对于程序要读取的文件,尽可能放到CLASSPATH下,这样就能保证在开发和发布时候均正常读取。

Java相对路径读取文件的更多相关文章

  1. java 使用相对路径读取文件

    java 使用相对路径读取文件 1.java project环境,使用java.io用相对路径读取文件的例子: *目录结构:  DecisionTree            |___src      ...

  2. Java FileReader使用相对路径读取文件

    Java FileReader使用相对路径读取文件 觉得有用的话,欢迎一起讨论相互学习~Follow Me 在进行编程时需要时常更换主机进行测试,如果使用绝对路径则需要经常更改,为此使用相对路径是一个 ...

  3. java多线程批量读取文件(七)

    新公司入职一个多月了,至今没有事情可以做,十来个新同事都一样抓狂,所以大家都自己学习一些新东西,我最近在看zookeeper,感觉蛮不错的,和微服务的zuul以及eureka功能类似,只是代码复杂了一 ...

  4. java中使用相对路径读取文件的写法总结 ,以及getResourceAsStream() (转)

    https://blog.csdn.net/my__sun_/article/details/74450241 读取文件的写法,相对路径 在当前的目录结构中读取test.txt的有四种写法 简单粗暴的 ...

  5. [JAVA 多种方式读取文件]

    package com.file; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream ...

  6. 【工具】JAVA 在单元读取文件并比较

    package test20140709; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; ...

  7. C# Note5:使用相对路径读取文件

    一.C#中使用相对路径读取配置文件 一般Solution的目录结构如下图所示: (如过看不到某些文件,可以点击 “显示所有文件” 图标) 方法一:由于生成的exe文件在bin\debug目录下,可以使 ...

  8. C#中winform使用相对路径读取文件的方法

    http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f73b6cd0d3027fa3cf1fd579080101 ...

  9. java多线程批量读取文件( 八)--读写分离

    package com.net.thread.future; import java.io.BufferedReader; import java.io.BufferedWriter; import ...

随机推荐

  1. find principles

    Computer Science An Overview _J. Glenn Brookshear _11th Edition In this chapter we explore the probl ...

  2. x5设置经典门户登录

    runtime\UIServer\index.jsp   java.lang.String url = request.getContextPath() + "/portal2/proces ...

  3. JAVA 调用matlab 出错总结

    1.Java:Unsupported major.minor version 51.0 (unable to load class 出现该错误是由于class编译器的JDK版本高于运行期的JDK版本. ...

  4. Linux的权限说明

    Linux的权限不是很细致,只有RWX三种r(Read,读取):对文件而言,具有读取文件内容的权限:对目录来说,具有浏览目录的权限.w(Write,写入):对文件而言,具有新增,修改,删除文件内容的权 ...

  5. 【转】get a mysterious problem,when i use HttpWebRequest in unity c# script

    in script,i use HttpWebRequest to get service from network.but it comes a mysterious problem. the so ...

  6. java override

    java override // 覆盖父类的方法,在子类直接调用子类内部这个方法时 public class TestCalc{ protected static class Wine{ String ...

  7. NSUserdefaults 简介以及存储自定义数据类型的方法

    一.了解NSUserDefaults以及它可以直接存储的类型 NSUserDefaults是一个单例,在整个程序中只有一个实例对象,他可以用于数据的永久保存,而且简单实用,这是它可以让数据自由传递的一 ...

  8. yum安装node.js

    1.安装EPEL库 yum install epel-release 2.安装Node.js yum install nodejs 3.安装nodejs中常用的npm软件包管理器 yum instal ...

  9. ArcGIS中利用ArcMap将地理坐标系转换成投影坐标系(从WKID=4326到WKID=102100)

    原文:ArcGIS中利用ArcMap将地理坐标系转换成投影坐标系(从WKID=4326到WKID=102100) 对于非地理专业的开发人员,对与这些生涩的概念,我们不一定都要了解,但是我们要理解,凡是 ...

  10. [LeetCode]题解(python):060-Permutation Sequence

    题目来源 https://leetcode.com/problems/permutation-sequence/ The set [1,2,3,…,n] contains a total of n! ...