Java讀取文件的問題

java讀取文件的兩種方法:java.io和java.lang.ClassLoader (我就知道這兩種.....)java

// java.io:  
File  file  =  new  File("...");  
FileInputStream  fis  =  new  FileInputStream("...");  
FileReader  fr  =  new  FileReader("...");  

//ClassLoader:  
ClassLoader  loader  =  XXXClass.class.getClassLoader();   
ClassLoader  loader2  =  Thread.currentThread().getContextClassLoader();  

URL  url  =  loader.getResource("...");  
File  file  =  new  File(url.getFile());  
InputStream  input  =  loader.getResourceAsStream("...");

java.io 包中的類老是根據當前用戶目錄來分析相對路徑名,也就是說相對路徑是否好使,取決於 user.dir 的值。系統屬性 user.dir 是 JVM 啓動的時候設置的,一般是 Java 虛擬機的調用目錄,即執行 java 命令所在的目錄web

對於 tomcat/jboss 容器,user.dir 是 %home/bin%/ 目錄,由於這個目錄就是咱們啓動 web 容器的地方spring

在 eclipse 中運行程序的時候,eclipse 會將 user.dir 的值設置爲工程的根目錄tomcat

用戶目錄可使用 System.getProperty("user.dir") 來查看框架

因此說,使用 java.io 讀取文件,不管是相對路徑,仍是絕對路徑都不是好的作法,能不使用就不要使用(在 JavaEE 中)。eclipse

使用ClassLoader

Class.getResource() 有 2 種方式,絕對路徑和相對路徑。絕對路徑以 / 開頭,從 classpath 或 jar 包根目錄下開始搜索;this

相對路徑是相對當前 class 所在的目錄,容許使用 ... 來定位文件。url

ClassLoader.getResource() 只能使用絕對路徑,並且不用以 / 開頭spa

這兩種方式讀取資源文件,不會依賴於 user.dir,也不會依賴於具體部署的環境,是推薦的作法(JavaEE).net

如何選取

  • java.io:
    相對於當前用戶目錄的相對路徑讀取;注重與磁盤文件打交道或者純 java project 中使用。
    雖然 ClassLoader 方式更通用,可是若是不是 javaEE 環境,要定位到 classpath 路徑下去讀文件是不合理的。

  • java.lang.ClassLoader:
    相對於 classpath 的相對路徑讀取;建議在 javaEE 環境中都使用這種方式。

一般,ClassLoader 不能讀取太大的文件,它適合讀取 web 項目的那些配置文件,若是須要讀取大文件,仍是要用 IO 包下的,能夠先經過 ClassLoader 獲取到文件的絕對路徑,而後傳給 File 或者其餘對象,用 io 包裏的對象去讀取會更好些

JavaEE

在 JavaEE 中獲取路徑還有一直方式,那就是 ServletContext 的 getRealPath 方法,它能夠得到物理路徑。

參數中 '/' 就表示當前的工程所在的目錄,能夠理解爲 WebRoot 所在的那個目錄。

附:Spring中ClassPathResource實現

Spring 能夠說是 JavaWeb 開發不可或缺的框架,它有提供 ClassPathResource 來讀取文件:

/** 
 * This implementation opens an InputStream for the given class path resource. 
 * @see java.lang.ClassLoader#getResourceAsStream(String) 
 * @see java.lang.Class#getResourceAsStream(String) 
 */  
public InputStream getInputStream() throws IOException {  
  InputStream is;  
  if (this.clazz != null) {  
    is = this.clazz.getResourceAsStream(this.path);  
  }  
  else {  
    is = this.classLoader.getResourceAsStream(this.path);  
  }  
  if (is == null) {  
    throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");  
  }  
  return is;  
}

能夠看出 spring 提供的 ClassPathResource,底層使用的就是 Class.getResource 或 ClassLoader.getResource()

參考

http://blog.csdn.net/aitangyong/article/details/36471881

相關文章
相關標籤/搜索