FastDFS文件的上傳和下載


一、FastDFS概述:

        FastDFS是一個開源的輕量級分布式文件系統,他對文件進行管理,功能包括:文件存儲、文件同步、文件訪問(文件上傳、下載)等,解決了大容量存儲和負載均衡的問題,高度追求高性能和擴展性。特別適合以文件為載體的在線服務,如相冊萬盞、視頻網站等等。

        FastDFS是由純C語言實現,支持Linux,FreeBSD的NUIX系統。類google FS,不是通用的文件系統,只能夠同故宮轉悠API進行訪問,目前提供了C,Java,PHP API。另外,FastDFS可以看作是基於文件的key-Value存儲系統,也可以稱之為 分布式文件存儲服務。

二、FastDFS提供的功能:

1、upload 上傳文件

2、upload_appender:上傳appender文件,后續可已對其進行append操作

3、upload_slave:上傳從文件

4、download 下載文件

5、delete 刪除文件

6、append:在已有文件后追加內容

7、set_metadata:設置文件附加屬性

8、get_metadata:獲取文件附加屬性

三、FastDFS的特點:

1、分組存儲、靈活簡潔

2、對等結構、不存在單點

3、文件ID有FastDFS生成,作為文件訪問憑證。FastDFS不需要傳統的name server

4、和流行的web server無縫連接,FastDFS已提供apache和nginx擴展模塊

5、大、中、小文件均可以很好支持,支持海量小文件存儲

6、支持多塊磁盤,支持但盤數據恢復

7、支持相同文件內容只保存一份,節省存儲空間

8、存儲服務器上可以保存文件附加屬性

9、下載文件支持多線程方式、支持斷點續傳

四、FastDFS架構解讀:

1、只有兩個角色,tracker server和storage server,不需要存儲文件索引信息

2、所有服務器都是對等的,不存在Master-Slave關系

3、存儲服務器采用分組方式,同組內存儲服務器上的文件完全相同

4、不同組的storage server之間不會相互通信

5、不同組的storage server之間不會相互通信

6、有storage server主動向tracker server報告狀態信息,tracker server 之間通常不會相互通信

 

五、FastDFS如何解決同步延遲問題?

1、storage生成的文件名中,包含源頭storage IP地址和文件創建的時間戳

2、源頭storage定時向tracker報告同步情況,包括向目標服務器同步到的文件時間戳

3、tracker收到storage的同步報告后,找出該組內每台storage被同步到的時間戳(取最小值),作為storage屬性保存到內存中

 

六、FastDFS擴展模塊要點:

1、使用擴展模塊來解決文件同步延遲問題

2、對每台storage server上部署web server,直接對外提供HTTP服務

3、tracker server上不需要部署web server

4、如果請求文件在當前storage上不存在,通過文件ID反解出源storage,直接請求源storage

5、目前已提供apache和nginx擴展模塊

6、FastDFS擴展模塊不依賴於FastDFS server,可以獨立存在

 

七、FastDFS擴展模塊特性:

1、僅支持HTTP HEAD和GET

2、支持token方式的防盜鏈(缺省是關閉的)

      -ts:生成token的時間(unix時間戳)

      -token:32未得token字符串(md5簽名)

3、支持制定保存的缺省文件名,URL參數名為filename

4、支持斷點續傳

 

FastDFS使用流程介紹:

 

 

 

 

三、實現流程:

1、配置依賴:因為我們使用的maven來管理工程,所以,我們需要去陪pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
    <modelVersion>4.0.0</modelVersion>   
    <groupId>com.leech</groupId>  
    <artifactId>fastdfs-demo</artifactId>  
    <version>0.0.1-SNAPSHOT</version>  
    <packaging>jar</packaging>   
    <name>fastdfs-demo</name>  
    <url>http://maven.apache.org</url>   
    <properties>    
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
    </properties>   
    
    <dependencies>    
        <dependency>      
            <groupId>junit</groupId>      
            <artifactId>junit</artifactId>      
            <version>4.11</version>      
            <scope>test</scope>    
        </dependency>         
        <dependency>      
            <groupId>org.csource</groupId>      
            <artifactId>fastdfs-client-java</artifactId>      
            <version>1.25</version>    
        </dependency>         
        <dependency>        
            <groupId>commons-io</groupId>        
            <artifactId>commons-io</artifactId>        
            <version>2.4</version>    
            </dependency>       
        </dependencies>
    </project>

2、新建fdfs_client.conf文件,在我們的itoo中,我們建立在(src/main/resources底下)

connect_timeout = 2
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 80 
#沒什么用
http.anti_steal_token = no
http.secret_key = FastDFS1234567890
tracker_server = 192.168.17.112:22122 
#tracker_server = 192.168.0.119:22122

3、實現文件上傳:

       public void save(HttpServletRequest request,HttpServletResponse response){        
        String videoName=request.getParameter("videoName");
        String videoType=request.getParameter("videoType");
        String videoDesc=request.getParameter("videoDesc");
        String videoPath=request.getParameter("videoPath");
        String picturePath=request.getParameter("picturePath");
 
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date uploadTime=null;
        try {
            uploadTime = formatter.parse(formatter.format(new Date()));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        JacksonJsonUntil jackJsonUtil =new JacksonJsonUntil ();
        
        String dataBaseName = "itoo_video";
    
        Video video=new Video();
        video.setUserName("why");
        video.setUserID("why");        
        video.setVideoName(videoName);
        video.setVideoPath(videoPath);
        video.setVideoType(videoType);
        video.setVideoDesc(videoDesc);    
        video.setDataBaseName(dataBaseName);
        video.setPicturePath(picturePath);
        video.setUploadTime(uploadTime);
        
        uploadFileService.save(video);        
        
        jackJsonUtil.beanToJson(response,video);
        
    }
    
    /*
     * 上傳文件
     */
    @RequestMapping(value={"/upload"})
    @ResponseBody
    public void upload( MultipartFile file, HttpServletRequest request,HttpServletResponse response){        
        
        String ext_Name = file.getOriginalFilename().split("\\.")[1];
        String videoName=file.getOriginalFilename().split("\\.")[0];
        
        byte[] bytes = null;
        try {
            bytes = file.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String videoPath=uploadFile(bytes,ext_Name);
        
        JacksonJsonUntil jackJsonUtil =new JacksonJsonUntil ();
        
        Video video=new Video();
        video.setVideoPath(videoPath);
        video.setVideoName(videoName);        
        
        jackJsonUtil.beanToJson(response,video);
    } 
    
    public String uploadFile(byte[] byteFile, String ext_file) {
        // 拼接服務區的文件路徑
        StringBuffer sbPath = new StringBuffer();
        sbPath.append("http://192.168.22.252");
        try {
            // 初始化文件資源
            ClientGlobal
                    .init("C:\\Users\\alsr\\Desktop\\ITOO-5.0\\itoo-video-Test\\dmsd-itoo-video-parent\\dmsd-itoo-video-web\\src\\main\\resources\\fdfs_client.conf");
 
            // 鏈接FastDFS服務器,創建tracker和Stroage
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();
            StorageServer storageServer = null;
            StorageClient storageClient = new StorageClient(trackerServer,
                    storageServer);
            //利用字節流上傳文件
            String[] strings = storageClient.upload_file(byteFile, ext_file, null);
 
            for (String string : strings) {
                sbPath.append("/" + string);
                System.out.println(string);
            }
            // 全路徑
            System.out.println(sbPath);
        } catch (IOException | MyException e) {
            e.printStackTrace();
        }
        return sbPath.toString();
    }

只要我們能正常接收到一個json類型的字符串(url地址),就證明我們已經上傳成功了,如果不信,可以直接用瀏覽器去驗證一下,看看能不能得到文件展示。

4、FastDFS實現文件下載:

public void testDownload() {        
        try {             
            ClientGlobal.init(conf_filename);             
            TrackerClient tracker = new TrackerClient();             
            TrackerServer trackerServer = tracker.getConnection();            
            StorageServer storageServer = null;             
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);             
            byte[] b = storageClient.download_file("group1", "M00/00/00/wKgRcFV_08OAK_KCAAAA5fm_sy874.conf");             
            System.out.println(b);             
            IOUtils.write(b, new FileOutputStream("D:/"+UUID.randomUUID().toString()+".conf"));        
            } 
        catch (Exception e) {             
            e.printStackTrace();         
        }     
    }       

5、FastDFS獲取將上傳文件信息:

public void testGetFileInfo(){         
        try {             
            ClientGlobal.init(conf_filename);             
            TrackerClient tracker = new TrackerClient();             
            TrackerServer trackerServer = tracker.getConnection();             
            StorageServer storageServer = null;             
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);             
            FileInfo fi = storageClient.get_file_info("group1", "M00/00/00/wKgRcFV_08OAK_KCAAAA5fm_sy874.conf");             
            System.out.println(fi.getSourceIpAddr());             System.out.println(fi.getFileSize());             
            System.out.println(fi.getCreateTimestamp());             System.out.println(fi.getCrc32());         
            }     
        catch (Exception e) {             
            e.printStackTrace();         
            }     
        }       

6、FastDFS獲取文件名稱:

    public void testGetFileMate(){         
            try {            
                ClientGlobal.init(conf_filename);             
                TrackerClient tracker = new TrackerClient();             
                TrackerServer trackerServer = tracker.getConnection();             
                StorageServer storageServer = null;             
                StorageClient storageClient = new StorageClient(trackerServer,                     
                storageServer);             
                NameValuePair nvps [] = storageClient.get_metadata("group1", "M00/00/00/wKgRcFV_08OAK_KCAAAA5fm_sy874.conf");             
                for(NameValuePair nvp : nvps){                 
                    System.out.println(nvp.getName() + ":" + nvp.getValue());            
                    }         
                } 
            catch (Exception e) {             
                e.printStackTrace();         
                }     
        }    

7、FastDFS實現刪除文件:

             public void testDelete(){         
            try {             
                ClientGlobal.init(conf_filename);             
                TrackerClient tracker = new TrackerClient();             
                TrackerServer trackerServer = tracker.getConnection();             
                StorageServer storageServer = null;             
                StorageClient storageClient = new StorageClient(trackerServer,storageServer);             
                int i = storageClient.delete_file("group1", "M00/00/00/wKgRcFV_08OAK_KCAAAA5fm_sy874.conf");             
                System.out.println( i==0 ? "刪除成功" : "刪除失敗:"+i);         
                } 
            catch (Exception e) {             
                e.printStackTrace();         
                }     
             }

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM