天天看點

在Java裡處理檔案的技巧

寫這篇blog,主要是因為看到太多的淩亂的,不安全的處理檔案的代碼了。甚至可以說每個項目都會有人喜歡寫自己的一些fileuitl。。

下面介紹一些利用jdk7标準庫來靈活處理檔案的方法。

有一些很靈活的處理方法: 

不好的代碼: 

即使是要手動拼接路徑,請使用下面兩個平台無關的變量: 

正确簡潔的方法是使用paths類: 

讀取檔案所有内容前,先判斷檔案大小,防止oom。 

dk7新特性,filevisitor 

網上流傳一種遞歸判斷parent的方式,http://stackoverflow.com/questions/18227634/check-if-file-is-in-subdirectory

但是查閱jdk代碼後,發現getparent()函數是通過處理檔案名得到的。是以直接比較檔案字首即可。 

請務必注意,file.getcanonicalpath()函數 。

jdk7新特性,但是api比較難用。todo 

淘寶有個diamond的配置管理項目,是利用定時器不斷去讀取來檔案是否改變的。

jdk7則是利用了linux的inotify機制。

字元截斷攻擊和檔案曆遍漏洞原理:在檔案名中插入%00的url編碼,web伺服器會把%00後面的内容抛棄。 

例如這樣的url:http://www.test.com/../../../../etc/passwd%00.gif

防範方法

寫入檔案前,判斷檔案是否在父路徑下,參考上面的函數。 

利用java的安全機制 

tomcat的設定 

http://tomcat.apache.org/tomcat-7.0-doc/security-manager-howto.html

靜态資源不要自己手寫代碼去讀取,盡量使用web伺服器或者web架構的本身的靜态資源映射功能。

比如tomcat的預設自帶的defaultservlet:

spring mvc可以配置

或者使用spring mvc裡的defaultservlethttprequesthandler。這個預設優先級是最低的,也就是最後沒人處理的url會交給webserver本身的default servlet去處理。比如tomcat的就是上面所說的。

個人推薦使用defaultservlethttprequesthandler,因為web容器的檔案通路功能要比spring mvc自身的要強大。比如tomcat的defaultservlet支援etag,斷點續傳,緩存等。

參考:

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html

http://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/catalina/servlets/defaultservlet.java