一区二区三区欧美日韩,国产a级全部精品,久久一区国产http://www.aygfsteel.com/coolingverse/category/26254.html志未半斤, 才無八兩. 有苦有樂, 糊涂過活。zh-cnSat, 29 Sep 2007 14:56:05 GMTSat, 29 Sep 2007 14:56:05 GMT60Spring 的優秀工具類盤點(一):文件資源操作http://www.aygfsteel.com/coolingverse/articles/149364.htmlStanley SunStanley SunFri, 28 Sep 2007 14:00:00 GMThttp://www.aygfsteel.com/coolingverse/articles/149364.htmlhttp://www.aygfsteel.com/coolingverse/comments/149364.htmlhttp://www.aygfsteel.com/coolingverse/articles/149364.html#Feedback0http://www.aygfsteel.com/coolingverse/comments/commentRss/149364.htmlhttp://www.aygfsteel.com/coolingverse/services/trackbacks/149364.html文件資源的操作是應用程序中常見的功能,如當上傳一個文件后將其保存在特定目錄下,從指定地址加載一個配置文件等等。我們一般使用 JDK 的 I/O 處理類完成這些操作,但對于一般的應用程序來說,JDK 的這些操作類所提供的方法過于底層,直接使用它們進行文件操作不但程序編寫復雜而且容易產生錯誤。相比于 JDK 的 File,Spring 的 Resource 接口(資源概念的描述接口)抽象層面更高且涵蓋面更廣,Spring 提供了許多方便易用的資源操作工具類,它們大大降低資源操作的復雜度,同時具有更強的普適性。這些工具類不依賴于 Spring 容器,這意味著您可以在程序中象一般普通類一樣使用它們。

加載文件資源

Spring 定義了一個 org.springframework.core.io.Resource 接口,Resource 接口是為了統一各種類型不同的資源而定義的,Spring 提供了若干 Resource 接口的實現類,這些實現類可以輕松地加載不同類型的底層資源,并提供了獲取文件名、URL 地址以及資源內容的操作方法。

訪問文件資源

假設有一個文件地位于 Web 應用的類路徑下,您可以通過以下方式對這個文件資源進行訪問:

  • 通過 FileSystemResource 以文件系統絕對路徑的方式進行訪問;
  • 通過 ClassPathResource 以類路徑的方式進行訪問;
  • 通過 ServletContextResource 以相對于Web應用根目錄的方式進行訪問。

相比于通過 JDK 的 File 類訪問文件資源的方式,Spring 的 Resource 實現類無疑提供了更加靈活的操作方式,您可以根據情況選擇適合的 Resource 實現類訪問資源。下面,我們分別通過 FileSystemResource 和 ClassPathResource 訪問同一個文件資源:


清單 1. FileSourceExample

package com.baobaotao.io;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
public class FileSourceExample {
    public static void main(String[] args) {
        try {
            String filePath = 
            "D:/masterSpring/chapter23/webapp/WEB-INF/classes/conf/file1.txt";
            // ① 使用系統文件路徑方式加載文件
            Resource res1 = new FileSystemResource(filePath); 
            // ② 使用類路徑方式加載文件
            Resource res2 = new ClassPathResource("conf/file1.txt");
            InputStream ins1 = res1.getInputStream();
            InputStream ins2 = res2.getInputStream();
            System.out.println("res1:"+res1.getFilename());
            System.out.println("res2:"+res2.getFilename());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在獲取資源后,您就可以通過 Resource 接口定義的多個方法訪問文件的數據和其它的信息:如您可以通過 getFileName() 獲取文件名,通過 getFile() 獲取資源對應的 File 對象,通過 getInputStream() 直接獲取文件的輸入流。此外,您還可以通過 createRelative(String relativePath) 在資源相對地址上創建新的資源。

在 Web 應用中,您還可以通過 ServletContextResource 以相對于 Web 應用根目錄的方式訪問文件資源,如下所示:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<jsp:directive.page import="
    org.springframework.web.context.support.ServletContextResource"/>
<jsp:directive.page import="org.springframework.core.io.Resource"/>
<%
    // ① 注意文件資源地址以相對于 Web 應用根路徑的方式表示
    Resource res3 = new ServletContextResource(application, 
        "/WEB-INF/classes/conf/file1.txt");
    out.print(res3.getFilename());
%>

對于位于遠程服務器(Web 服務器或 FTP 服務器)的文件資源,您則可以方便地通過 UrlResource 進行訪問。

為了方便訪問不同類型的資源,您必須使用相應的 Resource 實現類,是否可以在不顯式使用 Resource 實現類的情況下,僅根據帶特殊前綴的資源地址直接加載文件資源呢?Spring 提供了一個 ResourceUtils 工具類,它支持"classpath:"和"file:"的地址前綴,它能夠從指定的地址加載文件資源,請看下面的例子:


清單 2. ResourceUtilsExample

package com.baobaotao.io;
import java.io.File;
import org.springframework.util.ResourceUtils;
public class ResourceUtilsExample {
    public static void main(String[] args) throws Throwable{
        File clsFile = ResourceUtils.getFile("classpath:conf/file1.txt");
        System.out.println(clsFile.isFile());

        String httpFilePath = "file:D:/masterSpring/chapter23/src/conf/file1.txt";
        File httpFile = ResourceUtils.getFile(httpFilePath);
        System.out.println(httpFile.isFile());        
    }
}

ResourceUtils 的 getFile(String resourceLocation) 方法支持帶特殊前綴的資源地址,這樣,我們就可以在不和 Resource 實現類打交道的情況下使用 Spring 文件資源加載的功能了。

本地化文件資源

本地化文件資源是一組通過本地化標識名進行特殊命名的文件,Spring 提供的 LocalizedResourceHelper 允許通過文件資源基名和本地化實體獲取匹配的本地化文件資源并以 Resource 對象返回。假設在類路徑的 i18n 目錄下,擁有一組基名為 message 的本地化文件資源,我們通過以下實例演示獲取對應中國大陸和美國的本地化文件資源:


清單 3. LocaleResourceTest

package com.baobaotao.io;
import java.util.Locale;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.LocalizedResourceHelper;
public class LocaleResourceTest {
    public static void main(String[] args) {
        LocalizedResourceHelper lrHalper = new LocalizedResourceHelper();
        // ① 獲取對應美國的本地化文件資源
        Resource msg_us = lrHalper.findLocalizedResource("i18n/message", ".properties", 
        Locale.US);
        // ② 獲取對應中國大陸的本地化文件資源
        Resource msg_cn = lrHalper.findLocalizedResource("i18n/message", ".properties", 
        Locale.CHINA);
        System.out.println("fileName(us):"+msg_us.getFilename()); 
        System.out.println("fileName(cn):"+msg_cn.getFilename());
    }
}

雖然 JDK 的 java.util.ResourceBundle 類也可以通過相似的方式獲取本地化文件資源,但是其返回的是 ResourceBundle 類型的對象。如果您決定統一使用 Spring 的 Resource 接表征文件資源,那么 LocalizedResourceHelper 就是獲取文件資源的非常適合的幫助類了。

文件操作

在使用各種 Resource 接口的實現類加載文件資源后,經常需要對文件資源進行讀取、拷貝、轉存等不同類型的操作。您可以通過 Resource 接口所提供了方法完成這些功能,不過在大多數情況下,通過 Spring 為 Resource 所配備的工具類完成文件資源的操作將更加方便。

文件內容拷貝

第一個我們要認識的是 FileCopyUtils,它提供了許多一步式的靜態操作方法,能夠將文件內容拷貝到一個目標 byte[]、String 甚至一個輸出流或輸出文件中。下面的實例展示了 FileCopyUtils 具體使用方法:


清單 4. FileCopyUtilsExample

package com.baobaotao.io;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.OutputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.FileCopyUtils;
public class FileCopyUtilsExample {
    public static void main(String[] args) throws Throwable {
        Resource res = new ClassPathResource("conf/file1.txt");
        // ① 將文件內容拷貝到一個 byte[] 中
        byte[] fileData = FileCopyUtils.copyToByteArray(res.getFile());
        // ② 將文件內容拷貝到一個 String 中
        String fileStr = FileCopyUtils.copyToString(new FileReader(res.getFile()));
        // ③ 將文件內容拷貝到另一個目標文件
        FileCopyUtils.copy(res.getFile(), 
        new File(res.getFile().getParent()+ "/file2.txt"));

        // ④ 將文件內容拷貝到一個輸出流中
        OutputStream os = new ByteArrayOutputStream();
        FileCopyUtils.copy(res.getInputStream(), os);
    }
}

往往我們都通過直接操作 InputStream 讀取文件的內容,但是流操作的代碼是比較底層的,代碼的面向對象性并不強。通過 FileCopyUtils 讀取和拷貝文件內容易于操作且相當直觀。如在 ① 處,我們通過 FileCopyUtils 的 copyToByteArray(File in) 方法就可以直接將文件內容讀到一個 byte[] 中;另一個可用的方法是 copyToByteArray(InputStream in),它將輸入流讀取到一個 byte[] 中。

如果是文本文件,您可能希望將文件內容讀取到 String 中,此時您可以使用 copyToString(Reader in) 方法,如 ② 所示。使用 FileReader 對 File 進行封裝,或使用 InputStreamReader 對 InputStream 進行封裝就可以了。

FileCopyUtils 還提供了多個將文件內容拷貝到各種目標對象中的方法,這些方法包括:

方法 說明
static void copy(byte[] in, File out) 將 byte[] 拷貝到一個文件中
static void copy(byte[] in, OutputStream out) 將 byte[] 拷貝到一個輸出流中
static int copy(File in, File out) 將文件拷貝到另一個文件中
static int copy(InputStream in, OutputStream out) 將輸入流拷貝到輸出流中
static int copy(Reader in, Writer out) 將 Reader 讀取的內容拷貝到 Writer 指向目標輸出中
static void copy(String in, Writer out) 將字符串拷貝到一個 Writer 指向的目標中

在實例中,我們雖然使用 Resource 加載文件資源,但 FileCopyUtils 本身和 Resource 沒有任何關系,您完全可以在基于 JDK I/O API 的程序中使用這個工具類。

屬性文件操作

我們知道可以通過 java.util.Properties的load(InputStream inStream) 方法從一個輸入流中加載屬性資源。Spring 提供的 PropertiesLoaderUtils 允許您直接通過基于類路徑的文件地址加載屬性資源,請看下面的例子:

package com.baobaotao.io;
import java.util.Properties;
import org.springframework.core.io.support.PropertiesLoaderUtils;
public class PropertiesLoaderUtilsExample {
    public static void main(String[] args) throws Throwable {    
        // ① jdbc.properties 是位于類路徑下的文件
        Properties props = PropertiesLoaderUtils.loadAllProperties("jdbc.properties");
        System.out.println(props.getProperty("jdbc.driverClassName"));
    }
}

一般情況下,應用程序的屬性文件都放置在類路徑下,所以 PropertiesLoaderUtils 比之于 Properties#load(InputStream inStream) 方法顯然具有更強的實用性。此外,PropertiesLoaderUtils 還可以直接從 Resource 對象中加載屬性資源:

方法 說明
static Properties loadProperties(Resource resource) 從 Resource 中加載屬性
static void fillProperties(Properties props, Resource resource) 將 Resource 中的屬性數據添加到一個已經存在的 Properties 對象中

特殊編碼的資源

當您使用 Resource 實現類加載文件資源時,它默認采用操作系統的編碼格式。如果文件資源采用了特殊的編碼格式(如 UTF-8),則在讀取資源內容時必須事先通過 EncodedResource 指定編碼格式,否則將會產生中文亂碼的問題。


清單 5. EncodedResourceExample

package com.baobaotao.io;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.util.FileCopyUtils;
public class EncodedResourceExample {
        public static void main(String[] args) throws Throwable  {
            Resource res = new ClassPathResource("conf/file1.txt");
            // ① 指定文件資源對應的編碼格式(UTF-8)
            EncodedResource encRes = new EncodedResource(res,"UTF-8");
            // ② 這樣才能正確讀取文件的內容,而不會出現亂碼
            String content  = FileCopyUtils.copyToString(encRes.getReader());
            System.out.println(content);  
    }
}

EncodedResource 擁有一個 getResource() 方法獲取 Resource,但該方法返回的是通過構造函數傳入的原 Resource 對象,所以必須通過 EncodedResource#getReader() 獲取應用編碼后的 Reader 對象,然后再通過該 Reader 讀取文件的內容。



Stanley Sun 2007-09-28 22:00 發表評論
]]>
主站蜘蛛池模板: 闽侯县| 女性| 西乌珠穆沁旗| 镇江市| 玉溪市| 渝中区| 青河县| 上饶县| 丹阳市| 突泉县| 兰溪市| 尚义县| 奎屯市| 革吉县| 亳州市| 宁阳县| 石景山区| 湘潭市| 淄博市| 金塔县| 浠水县| 鄂托克旗| 来凤县| 富民县| 定州市| 韶关市| 海丰县| 凤翔县| 丹巴县| 崇信县| 延川县| 财经| 太谷县| 凌源市| 江都市| 四子王旗| 定州市| 仪陇县| 湖北省| 南宫市| 永仁县|