前言:这些天遇到不少文件路径的问题,有读写widows下文件路径的问题,也有在linux下读写文件路径的问题,所以搜来一些资料,大家共享! ========================================================================= 1.如何获得当前文件路径 常用: 字符串类型:System.getProperty("user.dir"); 综合: package com.zcjl.test.base; import java.io.File; public class Test { public static void main(String[] args) throws Exception { System.out.println( Thread.currentThread().getContextClassLoader().getResource("")); System.out.println(Test.class.getClassLoader().getResource("")); System.out.println(ClassLoader.getSystemResource("")); System.out.println(Test.class.getResource("")); System.out.println(Test.class.getResource("/")); System.out.println(new File("").getAbsolutePath()); System.out.println(System.getProperty("user.dir")); } } 2.Web服务中 (1).Weblogic WebApplication的系统文件根目录是你的weblogic安装所在根目录。 例如:如果你的weblogic安装在c:/bea/weblogic700..... 那么,你的文件根路径就是c:/. 所以,有两种方式能够让你访问你的服务器端的文件: a.使用绝对路径: 比如将你的参数文件放在c:/yourconfig/yourconf.properties, 直接使用 new FileInputStream("yourconfig/yourconf.properties"); b.使用相对路径: 相对路径的根目录就是你的webapplication的根路径,即WEB-INF的上一级目录,将你的参数文件放在yourwebapp/yourconfig/yourconf.properties, 这样使用: new FileInputStream("./yourconfig/yourconf.properties"); 这两种方式均可,自己选择。 (2).Tomcat 在类中输出System.getProperty("user.dir");显示的是%Tomcat_Home%/bin (3).Resin 不是你的JSP放的相对路径,是JSP引擎执行这个JSP编译成SERVLET 的路径为根.比如用新建文件法测试File f = new File("a.htm"); 这个a.htm在resin的安装目录下 (4).如何读相对路径哪? 在Java文件中getResource或getResourceAsStream均可 例:getClass().getResourceAsStream(filePath);//filePath可以是"/filename",这里的/代表web发布根路径下WEB-INF/classes (5).获得文件真实路径 string file_real_path=request.getRealPath("mypath/filename"); 通常使用request.getRealPath("/"); 3.文件操作的类 import java.io.*; import java.net.*; import java.util.*; //import javax.swing.filechooser.*; //import org.jr.swing.filter.*; /** * 此类中封装一些常用的文件操作。 * 所有方法都是静态方法,不需要生成此类的实例, * 为避免生成此类的实例,构造方法被申明为private类型的。 * @since 0.1 */ public class FileUtil { /** * 私有构造方法,防止类的实例化,因为工具类不需要实例化。 */ private FileUtil() { } /** * 修改文件的最后访问时间。 * 如果文件不存在则创建该文件。 * 目前这个方法的行为方式还不稳定,主要是方法有些信息输出,这些信息输出是否保留还在考 * @param file 需要修改最后访问时间的文件。 * @since 0.1 */ public static void touch(File file) { long currentTime = System.currentTimeMillis(); if (!file.exists()) { System.err.println("file not found:" + file.getName()); System.err.println("Create a new file:" + file.getName()); try { if (file.createNewFile()) { // System.out.println("Succeeded!"); } else { // System.err.println("Create file failed!"); } } catch (IOException e) { // System.err.println("Create file failed!"); e.printStackTrace(); } } boolean result = file.setLastModified(currentTime); if (!result) { // System.err.println("touch failed: " + file.getName()); } } 虑中。 /** * 修改文件的最后访问时间。 * 如果文件不存在则创建该文件。 * 目前这个方法的行为方式还不稳定,主要是方法有些信息输出,这些信息输出是否保留还在考 * @param fileName 需要修改最后访问时间的文件的文件名。 * @since 0.1 */ public static void touch(String fileName) { File file = new File(fileName); touch(file); } 虑中。 /** * 修改文件的最后访问时间。 * 如果文件不存在则创建该文件。 * 目前这个方法的行为方式还不稳定,主要是方法有些信息输出,这些信息输出是否保留还在考 * @param files 需要修改最后访问时间的文件数组。 * @since 0.1 */ public static void touch(File[] files) { for (int i = 0; i < files.length; i++) { touch(files); } } 虑中。 /** * 修改文件的最后访问时间。 * 如果文件不存在则创建该文件。 * 目前这个方法的行为方式还不稳定,主要是方法有些信息输出,这些信息输出是否保留还在考 * @param fileNames 需要修改最后访问时间的文件名数组。 * @since 0.1 */ public static void touch(String[] fileNames) { File[] files = new File[fileNames.length]; for (int i = 0; i < fileNames.length; i++) { files = new File(fileNames); } touch(files); } 虑中。 /** * 判断指定的文件是否存在。 * @param fileName 要判断的文件的文件名 * @return 存在时返回true,否则返回false。 * @since 0.1 */ public static boolean isFileExist(String fileName) { return new File(fileName).isFile(); } /** * 创建指定的目录。 * 如果指定的目录的父目录不存在则创建其目录书上所有需要的父目录。 * 注意:可能会在返回false的时候创建部分父目录。 * @param file 要创建的目录 * @return 完全创建成功时返回true,否则返回false。 * @since 0.1 */ public static boolean makeDirectory(File file) { File parent = file.getParentFile(); if (parent != null) { return parent.mkdirs(); } return false; } /** * 创建指定的目录。 * 如果指定的目录的父目录不存在则创建其目录书上所有需要的父目录。 * 注意:可能会在返回false的时候创建部分父目录。 * @param fileName 要创建的目录的目录名 * @return 完全创建成功时返回true,否则返回false。 * @since 0.1 */ public static boolean makeDirectory(String fileName) { File file = new File(fileName); return makeDirectory(file); } /** * 清空指定目录中的文件。 * 这个方法将尽可能删除所有的文件,但是只要有一个文件没有被删除都会返回false。 * 另外这个方法不会迭代删除,即不会删除子目录及其内容。 * @param directory 要清空的目录 * @return 目录下的所有文件都被成功删除时返回true,否则返回false. * @since 0.1 */ public static boolean emptyDirectory(File directory) { boolean result = false; File[] entries = directory.listFiles(); for (int i = 0; i < entries.length; i++) { if (!entries.delete()) { result = false; } } return true; } /** * 清空指定目录中的文件。 * 这个方法将尽可能删除所有的文件,但是只要有一个文件没有被删除都会返回false。 * 另外这个方法不会迭代删除,即不会删除子目录及其内容。 * @param directoryName 要清空的目录的目录名 * @return 目录下的所有文件都被成功删除时返回true,否则返回false。 * @since 0.1 */ public static boolean emptyDirectory(String directoryName) { File dir = new File(directoryName); return emptyDirectory(dir); } /** * 删除指定目录及其中的所有内容。 * @param dirName 要删除的目录的目录名 * @return 删除成功时返回true,否则返回false。 * @since 0.1 */ public static boolean deleteDirectory(String dirName) { return deleteDirectory(new File(dirName)); } /** * 删除指定目录及其中的所有内容。 * @param dir 要删除的目录 * @return 删除成功时返回true,否则返回false。 * @since 0.1 */ public static boolean deleteDirectory(File dir) { if ( (dir == null) || !dir.isDirectory()) { throw new IllegalArgumentException("Argument " + dir + " is not a directory. "); } File[] entries = dir.listFiles(); int sz = entries.length; for (int i = 0; i < sz; i++) { if (entries.isDirectory()) { if (!deleteDirectory(entries)) { return false; } } else { if (!entries.delete()) { return false; } } } if (!dir.delete()) { return false; } return true; } /** * 返回文件的URL地址。 * @param file 文件 * @return 文件对应的的URL地址 * @throws MalformedURLException * @since 0.4 * @deprecated 在实现的时候没有注意到File类本身带一个toURL方法将文件路径转换为URL。 * 请使用File.toURL方法。 */ public static URL getURL(File file) throws MalformedURLException { String fileURL = "file:/" + file.getAbsolutePath(); URL url = new URL(fileURL); return url; } /** * 从文件路径得到文件名。 * @param filePath 文件的路径,可以是相对路径也可以是绝对路径 * @return 对应的文件名 * @since 0.4 */ public static String getFileName(String filePath) { File file = new File(filePath); return file.getName(); } /** * 从文件名得到文件绝对路径。 * @param fileName 文件名 * @return 对应的文件路径 * @since 0.4 */ public static String getFilePath(String fileName) { File file = new File(fileName); return file.getAbsolutePath(); } /** * 将DOS/Windows格式的路径转换为UNIX/Linux格式的路径。 * 其实就是将路径中的"/"全部换为"/",因为在某些情况下我们转换为这种方式比较方便, * 某中程度上说"/"比"/"更适合作为路径分隔符,而且DOS/Windows也将它当作路径分隔符。 * @param filePath 转换前的路径 * @return 转换后的路径 * @since 0.4 */ public static String toUNIXpath(String filePath) { return filePath.replace('//', '/'); } /** * 从文件名得到UNIX风格的文件绝对路径。 * @param fileName 文件名 * @return 对应的UNIX风格的文件路径 * @since 0.4 * @see #toUNIXpath(String filePath) toUNIXpath */ public static String getUNIXfilePath(String fileName) { File file = new File(fileName); return toUNIXpath(file.getAbsolutePath()); } /** * 得到文件的类型。 * 实际上就是得到文件名中最后一个“.”后面的部分。 * @param fileName 文件名 * @return 文件名中的类型部分 * @since 0.5 */ public static String getTypePart(String fileName) { int point = fileName.lastIndexOf('.'); int length = fileName.length(); if (point == -1 || point == length - 1) { return ""; } else { return fileName.substring(point + 1, length); } } /** * 得到文件的类型。 * 实际上就是得到文件名中最后一个“.”后面的部分。 * @param file 文件 * @return 文件名中的类型部分 * @since 0.5 */ public static String getFileType(File file) { return getTypePart(file.getName()); } /** * 得到文件的名字部分。 * 实际上就是路径中的最后一个路径分隔符后的部分。 * @param fileName 文件名 * @return 文件名中的名字部分 * @since 0.5 */ public static String getNamePart(String fileName) { int point = getPathLsatIndex(fileName); int length = fileName.length(); if (point == -1) { return fileName; } else if (point == length - 1) { int secondPoint = getPathLsatIndex(fileName, point - 1); if (secondPoint == -1) { if (length == 1) { return fileName; } else { return fileName.substring(0, point); } } else { return fileName.substring(secondPoint + 1, point); } } else { return fileName.substring(point + 1); } } /** * 得到文件名中的父路径部分。 * 对两种路径分隔符都有效。 * 不存在时返回""。 * 如果文件名是以路径分隔符结尾的则不考虑该分隔符,例如"/path/"返回""。 * @param fileName 文件名 * @return 父路径,不存在或者已经是父目录时返回"" * @since 0.5 */ public static String getPathPart(String fileName) { int point = getPathLsatIndex(fileName); int length = fileName.length(); if (point == -1) { return ""; } else if (point == length - 1) { int secondPoint = getPathLsatIndex(fileName, point - 1); if (secondPoint == -1) { return ""; } else { return fileName.substring(0, secondPoint); } } else { return fileName.substring(0, point); } } /** * 得到路径分隔符在文件路径中首次出现的位置。 * 对于DOS或者UNIX风格的分隔符都可以。 * @param fileName 文件路径 * @return 路径分隔符在路径中首次出现的位置,没有出现时返回-1。 * @since 0.5 */ public static int getPathIndex(String fileName) { int point = fileName.indexOf('/'); if (point == -1) { point = fileName.indexOf('//'); } return point; } /** * 得到路径分隔符在文件路径中指定位置后首次出现的位置。 * 对于DOS或者UNIX风格的分隔符都可以。 * @param fileName 文件路径 * @param fromIndex 开始查找的位置 * @return 路径分隔符在路径中指定位置后首次出现的位置,没有出现时返回-1。 * @since 0.5 */ public static int getPathIndex(String fileName, int fromIndex) { int point = fileName.indexOf('/', fromIndex); if (point == -1) { point = fileName.indexOf('//', fromIndex); } return point; } /** * 得到路径分隔符在文件路径中最后出现的位置。 * 对于DOS或者UNIX风格的分隔符都可以。 * @param fileName 文件路径 * @return 路径分隔符在路径中最后出现的位置,没有出现时返回-1。 * @since 0.5 */ public static int getPathLsatIndex(String fileName) { int point = fileName.lastIndexOf('/'); if (point == -1) { point = fileName.lastIndexOf('//'); } return point; } /** * 得到路径分隔符在文件路径中指定位置前最后出现的位置。 * 对于DOS或者UNIX风格的分隔符都可以。 * @param fileName 文件路径 * @param fromIndex 开始查找的位置 * @return 路径分隔符在路径中指定位置前最后出现的位置,没有出现时返回-1。 * @since 0.5 */ public static int getPathLsatIndex(String fileName, int fromIndex) { int point = fileName.lastIndexOf('/', fromIndex); if (point == -1) { point = fileName.lastIndexOf('//', fromIndex); } return point; } /** * 将文件名中的类型部分去掉。 * @param filename 文件名 * @return 去掉类型部分的结果 * @since 0.5 */ public static String trimType(String filename) { int index = filename.lastIndexOf("."); if (index != -1) { return filename.substring(0, index); } else { return filename; } } /** * 得到相对路径。 * 文件名不是目录名的子节点时返回文件名。 * @param pathName 目录名 * @param fileName 文件名 * @return 得到文件名相对于目录名的相对路径,目录下不存在该文件时返回文件名 * @since 0.5 */ public static String getSubpath(String pathName,String fileName) { int index = fileName.indexOf(pathName); if (index != -1) { return fileName.substring(index + pathName.length() + 1); } else { return fileName; } } } 4.遗留问题 目前new FileInputStream()只会使用绝对路径,相对没用过,因为要相对于web服务器地址,比较麻烦 还不如写个配置文件来的快哪 5.按Java文件类型分类读取配置文件
配置文件是应用系统中不可缺少的,可以增加程序的灵活性。java.util.Properties是从jdk1.2就有的类,一直到现在都支持load()方法,jdk1.4以后save(output,string) ->store(output,string)。如果只是单纯的读,根本不存在烦恼的问题。web层可以通过Thread.currentThread().getContextClassLoader(). getResourceAsStream("xx.properties")获取;Application可以通过new FileInputStream("xx.properties");直接在classes一级获取。关键是有时我们需要通过web修改配置文件,我们不能将路径写死了。经过测试觉得有以下心得:
1.servlet中读写。如果运用Struts或者Servlet可以直接在初始化参数中配置,调用时根据servlet的getRealPath("/")获取真实路径,再根据String file = this.servlet.getInitParameter("abc");获取相对的WEB-INF的相对路径。 例: InputStream input = Thread.currentThread().getContextClassLoader(). getResourceAsStream("abc.properties"); Properties prop = new Properties(); prop.load(input); input.close(); OutputStream out = new FileOutputStream(path); prop.setProperty("abc", “test"); prop.store(out, “–test–"); out.close();
2.直接在jsp中操作,通过jsp内置对象获取可操作的绝对地址。 例: // jsp页面 String path = pageContext.getServletContext().getRealPath("/"); String realPath = path+"/WEB-INF/classes/abc.properties";
//java 程序 InputStream in = getClass().getClassLoader().getResourceAsStream("abc.properties"); // abc.properties放在webroot/WEB-INF/classes/目录下 prop.load(in); in.close();
OutputStream out = new FileOutputStream(path); // path为通过页面传入的路径 prop.setProperty("abc", “abcccccc"); prop.store(out, “–test–"); out.close();
3.只通过Java程序操作资源文件 InputStream in = new FileInputStream("abc.properties"); // 放在classes同级
OutputStream out = new FileOutputStream("abc.properties");
|