天天看點

fastDFS分布式檔案系統與檔案上傳下載下傳

傳統的檔案上傳方式就是将檔案直接上傳儲存到項目伺服器中,這樣做有以下幾個缺點:

1.容錯性差,如果伺服器出現問題有可能導緻上傳檔案丢失

2.占用伺服器資源,上傳檔案過多會大量消耗伺服器資源導緻系統性能下降

3.不适應于叢集環境,有可能出現上傳與下載下傳不在同一個伺服器中。

傳統的檔案上傳方式很明顯不适用與網際網路項目,解決方案就是使用第三方伺服器存儲上傳檔案。fastDFS是阿裡巴巴開發的開源的輕量級分布式檔案系統,具有高可用、高并發、可拓展的優點,符合網際網路項目的需求。

fastDFS分布式檔案系統的特點:
1.作為第三方伺服器分布式檔案系統存儲檔案,提高了容錯性
2.上傳與下載下傳統一在fastDFS進行,解決了叢集資源共享問題
3.浏覽器通路遠端伺服器圖檔或靜态頁面時,需要遵循http協定,可以通過ngnix作為http伺服器通路fastDFS的資源。

fastDFS在項目中實作檔案上傳的環境要求:
1.jar包(pom導入坐标)  commos-io  commos-fileupload  fastDFS-client
2.配置檔案上傳解析器(在springmvc中配置)
3.用戶端配置client.conf連接配接fastDFS伺服器
           

附上項目圖檔上傳部分代碼:

前端頁面部分

<a class="easyui-linkbutton file" iconCls="icon-upload" >
                         <form id="upload_form">
                            <font size=>本地上傳</font>
                            <input type="file" onchange="doUploadPhoto()" name="file" class="easyui-validatebox" validType="img_upload" />
                         </form>
                    </a>

function doUploadPhoto(){
    if ($('#upload_form').form('validate')) {
        var form = new FormData($("#upload_form")[]);
        var indexCode=$("#indexCode").val().trim();
        $.ajax({
                type: 'post' ,
                url:"<%=path%>/uploadPhotoPG?indexCode="+indexCode,
                cache:false ,
                data:form ,
                dataType:'json',
                processData:false,
                contentType:false,
                success:function(result){
                    $.messager.show({
                        title:"提示資訊", 
                        msg:"上傳成功"
                    });
                    setTimeout("location.reload(true)",);
                },
                error:function(result){
                    $.messager.show({
                        title:"提示資訊", 
                        msg:"未知錯誤"
                    });
                }
        });
    }
}
           

請求跳轉Controller部分

@ResponseBody
    @RequestMapping(value = "/uploadPhotoPG", method = { RequestMethod.POST})
    @Transactional(propagation=Propagation.REQUIRED)
    public Object  uploadPhotoPG(MultipartFile file,String checkId,String appMenuCode,String storeyId,String indexCode) {  
        try{
            UploadLocalOrWeb uploadLocalOrWeb = new UploadLocalOrWeb();
            String suffix = file.getOriginalFilename().split("\\.")[file.getOriginalFilename().split("\\.").length-];
            String url = uploadLocalOrWeb.uploadWeb(file.getBytes(), suffix);

            Photo photo = new Photo();
            photo.setId(UuidUtil.create());
            photo.setIndexCode(indexCode);
            photo.setUrl(url);
            photo.setUploadtime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            photo.setIsWriteReport("Y");
            photoService.create(photo);
            msg="上傳成功";
            code= "1";
            map.put("msg", msg);
            map.put("code", code);
        }catch(Exception e){
            //復原事務
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 
            e.printStackTrace();
            msg="上傳失敗";
            code= "-1";
            map.put("msg", msg);
            map.put("code", code);
        }

        return map;  
    }
           

fastDFS工具類(實作上傳功能)

package com.ra.fastdfs;

import java.io.File;
import java.io.InputStream;
import java.util.Properties;


/**
 * 上傳控制
 * 選擇上傳到本地  或是 上傳到遠端伺服器
 * @author MrC
 *
 */
public class UploadLocalOrWeb {
    //遠端伺服器位址
    @SuppressWarnings("unused")
    private static String proxy_server = "121.15..";

    @SuppressWarnings("unused")
    private static String http = "http://";

    //選擇從本地項目下載下傳還是從遠端伺服器下載下傳檔案
    private static String LoadFromLocalOrWeb = "web";

    /**
     * 讀取配置檔案
     * @throws Exception 
     */
    private void loadProperty() throws Exception {
        Properties prop=new Properties();
        InputStream is = this.getClass().getResourceAsStream("/fastdfs.properties");
        prop.load(is);
        is.close();
        proxy_server = prop.getProperty("proxy_server").trim(); 
        LoadFromLocalOrWeb = prop.getProperty("LoadFromLocalOrWeb").trim(); 
    }



    /**
     * 上傳到本地
     * @param buffer  上傳的檔案數組
     * @param path    如:D://upload/
     * @param fileExtName  如:"doc"
     * @param fileName      如:"image1"
     * @return
     */
    public String uploadLocal(byte[] buffer, String reqPath, String folder, String fileExtName, String fileName)throws Exception{
        String path = reqPath + File.separator + folder;
        String url = "";
        String filePathName = "";
        File file = new File(path);
        if (!file.exists()) { //判斷檔案夾是否存在,如果不存在則建立檔案夾
            file.mkdir();
        }

        FileAndByte fab = new FileAndByte();
        filePathName = fileName + FileUtils.randomName(fileExtName);
        fab.byte2File(buffer, path, filePathName);
        url = folder + File.separator + filePathName;
        return url;
    }

    /** 上傳到遠端伺服器 
     * @throws Exception **/
    public String uploadWeb(byte[] buffer,String fileExtName) throws Exception{
        FastDFSClient client = new FastDFSClient();
        String url,url2 = "";
        //調用遠端伺服器儲存檔案,傳回檔案儲存url
        url2 = client.upload(buffer,fileExtName);
        //url = http + proxy_server +":7788"+ File.separator + url;
        url = ReadPropertyUtil.getInstance("fastdfs.properties").getProperty("proxy_server").trim();
        String str = ReadPropertyUtil.getInstance("fastdfs.properties").getProperty("http.tracker_server_port").trim();
        url = "http://"+url + ":" + str + File.separator + url2 ;
        return url;
    }

    /**
     * @desc 圖檔壓縮上傳
     *         先上傳到本地,再壓縮,再上傳到圖檔真正上傳的位置
     * @author MrC
     * 實際上傳位址 reqPath + folder
     * @param buffer              上傳的檔案數組     ***必需
     * @param reqPath      如: D://images/    ***上傳到本地必需 request.getServletContext().getRealPath("/")
     * @param folder       如: upload/case/   ***上傳到本地必需  上傳檔案夾
     * @param fileName            如:"image1" ***上傳到本地必需
     * @param fileExtName  如:"doc"    ***上傳到遠端伺服器必需
     * @throws Exception 
     */
    public String compressImgAndUpload(byte[] buffer, String reqPath, String folder, String fileExtName, String fileName) throws Exception{
        String url = "";

        FileUtils fu = new FileUtils();
        FileAndByte fab = new FileAndByte();
        // 緩存圖檔
        url = uploadLocal(buffer, reqPath, "upload/cache", fileExtName, fileName);
        // 壓縮圖檔
        fu.compressPic(reqPath+File.separator+url);
        // 壓縮後的緩存圖檔 轉成 byte[] 以便上傳到檔案伺服器
        byte[] buff = fab.File2byte(reqPath+File.separator+url);
        // 調用遠端伺服器儲存檔案,傳回檔案儲存url
        url = DoUpload(buff, reqPath, folder, fileExtName, fileName);
        return url;
    }


    /**
     * 上傳到本地或是遠端伺服器
     * 實際上傳位址 reqPath + folder
     * @param buffer  上傳的檔案數組     ***必需
     * @param reqPath    如: D://images/    ***上傳到本地必需 request.getServletContext().getRealPath("/")
     * @param folder     如: upload/case/   ***上傳到本地必需  上傳檔案夾
     * @param fileName            如:"image1" ***上傳到本地必需
     * @param fileExtName  如:"doc"    ***上傳到遠端伺服器必需
     * @return
     * @throws Exception 
     */
    public String DoUpload(byte[] buffer, String reqPath, String folder, String fileExtName, String fileName) throws RuntimeException{
        String url = "";
        try {
            loadProperty();//讀取配置檔案
            if(LoadFromLocalOrWeb.equals("web")){
                //上傳至遠端伺服器
                url = uploadWeb(buffer, fileExtName);
            }else{
                //上傳至項目路徑
                url = uploadLocal(buffer, reqPath, folder, fileExtName, fileName);
            }
        } catch (Exception e) {
            throw new RuntimeException();
        }
        return url;
    }
}
           

繼續閱讀