1、FastDFS
1.1、了解基礎概念
1.1.1、什么是分布式文件系統?
- 全稱:Distributed File System,即簡稱的DFS
- 這個東西可以是一個軟件,也可以說是服務器,和Tomcat差不多,即相當于軟件也相當于是服務器,這個軟件就是用來管理文件的
- 這個軟件所管理的文件通常不是在一個服務器節點上,而是在多個服務器節點上
- 服務器節點通過網絡相連構成一個龐大的文件存儲服務器集群,這些服務器都用于存儲文件資源,通過分布式文件系統來管理這些服務器上的文件
1.1.2、傳統文件系統 和 分布式文件系統對比
傳統文件系統
- 缺點所有的文件都存放在一臺計算機中,如果這臺計算機掛彩了,那么就會導致整個服務不可用( 文件不能上傳和下載了 )如果這臺計算機磁盤損壞了,那么會丟失所有的文件這臺計算機的磁盤空間非常有限,很容易到達磁盤的上限,導致無法上傳文件
- 回顧玩servlet時的文件上傳和下載
- 文件上傳
- 假如前端轟html寫法是如下的樣子:
- <div id="image"> <label for="">標題圖片:</label> <input type="file" id="file" name="file" > <img src="" alt="" width="100px" height="150px"> </div>
- JS寫法如下:
- // 當圖片發生改變時 —— 也就是用戶點擊file框,上傳文件時 $("#file").on( 'change' , function () { // 創建一個FormData空對象,就相當于是偽造了一個form表單 let formData = new FormData(); // 這個FromData對象就用來裝文件內容 // 文件的files屬性本質是個數組 let files = $("#file").prop("files"); formData.Append("upFile" , files[0] ); $.ajax( { url: '/ajax/upload.do', type: 'post', data: formData, dataType: 'json', cache: false, // 上傳文件不需要緩存 contentType: false, // 不需要對內容類型進行處理 因為內容是一個FormData對象 processData: false, // 不需要對數據進行處理,因為上面的data是一個FormData對象 // 后臺返回的格式 : // { "errno":"0" , "data":[ {"alt":"1633528500498.jpg" , "url":"/upload/2021-10-06/1633528500498.jpg"} ] } success: function (info) { info.data.forEach( function (data) { // $("#image img").remove(); // $("#image").append( ' <img src=" '+data.url+' " alt="" width="100px" height="150px"> ' ) /* 注掉的這種是:html中沒有img標簽時使用 因為:使用下面這種方法的情景是 —— 頁面本來就有一個img框( 即:初始頁面上這個file本身有一張圖片 ),所以下面這種可以做到圖片改變時把圖片的路徑換掉,也就是圖片渲染( 也是數據回填 的思想 ) 但是:如果頁面一開始file的位置是不應該有圖片的,是后面用戶選了之后才出現圖片預覽效果,那么:就使用注釋掉的這種方法:追加 */ $("#image img").attr("src" , data.url ); }); } } ); })
- 那么后端的low代碼如下:
- import com.alibaba.fastjson.JSON; import JAVAx.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.File; import java.io.IOException; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; // @MultipartConfig 注解就是文件注解,要獲取前端的文件信息,必須加這個注解,不然做的所有事情都是無用功 @MultipartConfig @WebServlet("/ajax/upload.do") public class UploadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* * 想要構建的是這么一個玩意兒 * "errno":0 data:[ { url:"圖片地址“ } , { alt:"圖片說明“ } , { href:"null" } ] * * */ ArrayList<Object> list = new ArrayList<>(); Collection<Part> parts = req.getParts(); // 這是獲取前臺上傳的文件 for (Part part : parts) { // 先構建 data:[ { } , { } ]中的[ { } , { } ] // 獲取文件的全路徑 // 但是:不同瀏覽器的這個全路徑都不一樣,所以需要截取從而自定義文件名 String filePath = part.getSubmittedFileName(); // System.out.println(filePath); // 截取文件的后綴名 int subFileName = filePath.lastIndexOf("."); String fileSuffix = filePath.substring(subFileName); // 自己給文件重新定義一個名字,并規定存放的地方 String timeStr = LocalDate.now().toString(); // 獲取當前項目的一個指定文件夾名字,用來保存文件 注意:getRealPath這是獲取的當前項目的全路徑,即:從盤符開始的路徑 String proPathName = this.getServletContext().getRealPath("/upload/" + timeStr ); File file = new File(proPathName); if ( !file.exists() ){ file.mkdirs(); } // 拼接文件后綴名并保存文件 long timeStamp = new Date().getTime(); part.write(proPathName + "/" + timeStamp + fileSuffix ); HashMap<String, String> map = new HashMap<>(); map.put( "url" , "/upload/" + timeStr + "/" + timeStamp + fileSuffix ); map.put( "alt" , timeStamp + fileSuffix ); map.put( "href" , null ); list.add(map); } // 再構建"errno":0 data:[ { url:"圖片地址“ } , { alt:"圖片說明“ } , { href:"null" } ] HashMap<String, Object> map = new HashMap<>(); map.put("errno", "0"); map.put("data", list); resp.getWriter().print( JSON.toJSONString(map) ); } }
文件下載
- 后端low代碼如下
import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; @WebServlet("/downFile") public class downFileInClientServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1、獲取讓瀏覽器下載的文件路徑 String FileRealPath = "D:\JavaTrainStudy\servlet\out\production\study06-httpServletResponse\loginbg.png"; // 2、告知瀏覽器要下載的文件名是什么? String fileName = FileRealPath.substring( FileRealPath.lastIndexOf("\") + 1 ); // 3、讓瀏覽器支持文件下載 // Content-Disposition這個就是讓瀏覽器支持文件下載 // URLEncoder.encode( String s , String enc ) 是為了以防文件名是中文名,這樣就設置編碼格式了,讓瀏覽器能夠解析這個中文文件名 resp.setHeader("Content-Disposition" , "attachment ; filename=" + URLEncoder.encode(fileName , "utf-8")); // 4、獲取輸入、輸出流對象 并 把服務器中的文件輸出到瀏覽器上 FileInputStream fis = new FileInputStream( FileRealPath ); ServletOutputStream os = resp.getOutputStream(); // 創建緩沖區 int len = 0 ; byte[] buffer = new byte[1024]; while ( ( len = fis.read( buffer ) ) > 0 ){ os.write( buffer , 0 , len); } // 5、關閉流管道 if ( os != null ){ os.close(); } if ( fis != null ){ fis.close(); } } }
分布式文件系統
- 優點解決了傳統方式的單點故障問題若某一個節點出現故障,則還有其他的節點可以用來讀取和寫入文件提供數據備份從而避免磁盤損壞而導致的文件丟失提供擴容機制,無限增加文件存放的空間上限
1.2、認識FastDFS
補充:常見的分布式文件系統
- FastDFS、GFS、HDFS、Lustre 、Ceph 、GridFS 、mogileFS、TFS
1.2.1、了解FastDFS
- 官網:https://github.com/happyfish100/fastdfs
- FastDFS是一個開源的輕量級分布式文件系統,為互聯網應用量身定做,簡單、靈活、高效,采用C語言開發,由阿里巴巴開發并開源
- FastDFS對文件進行管理,功能包括:文件存儲、文件同步( 指的是:文件系統 和 數據備份之間的同步 )、文件上傳、文件下載、文件刪除等
- FastDFS解決了大容量文件存儲的問題
- FastDFS特別適合以文件為載體的在線服務,如相冊網站、文檔網站、圖片網站、視頻網站等
- FastDFS充分考慮了冗余備份、線性擴容等機制,并注重高可用、高性能等指標,使用FastDFS很容易搭建一套高性能的文件服務器集群提供文件上傳、下載等服務冗余備份:指的是文件系統中存的文件 和 數據備份中存的文件完全一致的問題線性擴容:文件系統 和 數據備份不斷增加唄( 就是上圖中再加幾份嘛 ),和水平擴容類似
1.2.2、FastDFS的組成結構
- 由兩大部分構成,一個是客戶端,一個是服務端客戶端:指我們的程序,比如我們的Java程序去連接FastDFS、操作FastDFS,那我們的Java程序就是一個客戶端。FastDFS提供專有API訪問,目前提供了C、Java和php幾種編程語言的API,用來訪問FastDFS文件系統服務端由兩個部分構成:一個是跟蹤器(tracker),一個是存儲節點(storage)跟蹤器 tracker:這個玩意兒類似于Erueka / zookeeper注冊中心,起到一個調度的作用。它是在內存中記錄集群中存儲節點storage的狀態信息,是前端Client和后端存儲節點storage的樞紐,因為相關信息全部在內存中,Tracker server的性能非常高,一個較大的集群(比如上百個group,group指的就是:文件系統 和 數據備份的組合,這二者就是一個group)中有3臺就足夠了存儲節點 storage:用于存儲文件,包括文件和文件屬性(meta data,如:文件名、文件大小、文件后綴...)都保存到存儲服務器磁盤上。以及完成文件管理的所有功能:文件存儲、文件同步和提供文件訪問( 上傳、下載、刪除 )等
2、開始玩FastDFS
2.1、安裝FastDFS
- 注:我的系統是centos 7
- 安裝需要的依賴環境 gcc、libevent、libevent-devel
yum install gcc libevent libevent-devel -y
- 安裝公共函數庫libfastcommon 和 fastDFS壓縮包自行去前面官網中進行下載,當然:官網的wiki中有在線拉取命令
- 解壓公共函數庫libfastcommon
tar -zxvf libfastcommon-1.0.36.tar.gz
- 進入libfastcommon,執行里面的make.sh,編譯公共函數
./make.sh # 當然:可以把命令進行合并 執行如下命令 就是編譯并安裝./make.sh && ./make.sh install
- 安裝公共函數
./make.sh install
- 解壓fastdfs-5.11.tar.gz壓縮包
tar -zxvf fastdfs-5.11.tar.gz
- 進入解壓之后的文件,使用make sh進行編譯
./make.sh # 一樣的可以用組合命令 即:編譯并安裝./make.sh && ./make.sh install
- 安裝
./make.sh install
- 檢查是否安裝成功,進入如下的目錄即可
cd /usr/bin
- 往后找,出現這些fdfs開頭的文件就表示成功( 這些文件就是fastDFS的相關命令 )
- fastDFS配置文件所在地,進入如下目錄即可
- 想要讓fastDFS的配置文件生效,那么就需要放到下面的這個目錄中
cd /etc/fdfs
- 拷貝兩個配置文件到etc/fdfs中,這兩個配置文件在解壓的fastDFS的conf中,一個叫http.conf,一個叫mime.types
# 供Nginx訪問使用cp http.conf /etc/fdfs # 供nginx訪問使用cp mime.types /etc/fdfs
2.2、啟動FastDFS
- 這個玩意兒不可以直接啟動,因為默認的配置文件中有一些關于文件目錄的配置是不存在的,因此:只要直接啟動就會報錯
2.2.1、修改配置文件
- 要修改的文件就兩個
- 以防萬一,因此:將上面的文件拷貝一份
/etc/fdfs mv storage.conf.sample ./storage.conf mv tracker.conf.sample ./tracker.conf
2.2..1.1、修改tracker.conf
- 在這個配置文件中有一個base_path配置,指向的是fastDFS作者余慶的地址,而我們自己的linux中并沒有這個目錄,因此:做修改
vim tracker.conf # 搜索此配置/base_path # 改成的值,也可以自定義自己的目錄( 注意:需要保證這個目錄必須存在,沒存在那就需要創建 )base_path=/opt/fastdfs/tracker
- 注意:需要保證這個目錄必須存在,沒存在那就需要創建
2.2.1.2、修改storage.conf
- 需要改的內容如下
# storage存儲數據目錄base_path=/opt/fastdfs/storage # 真正存放文件的目錄store_path0=/opt/fastdfs/storage/files # 注冊當前存儲節點的跟蹤器地址tracker_server=服務器ip:22122
- 注意:要是前面的那三個目錄沒有的話,記得創建,若指向的是已經創建好的目錄,那就不用創建了
mkdir -p /opt/fastdfs/tracker mkdir -p /opt/fastdfs/storage mkdir -p /opt/fastdfs/storage/files
2.2.2、開啟fastDFS
- 在任意目錄下,執行如下的命令即可
# 啟動tracker 要想看fdfs_trackerd的命令用法,那直接輸入fdfs_trackerd就可以彈出其用法了# 如:要關閉tracker,則命令為:fdfs_trackerd /etc/fdfs/tracker.conf stop# 開啟 | 重啟就是把stop改成start | restart即可fdfs_trackerd /etc/fdfs/tracker.conf # 啟動storagefdfs_storaged /etc/fdfs/storage.conf
- 查看是否啟動成功
ps -ef | grep fdfs
- 如下圖表示啟動成功
- 但是上面的啟動會有坑兒,所以需要確認一把
# 查看日志文件是否有報ERRORcat /opt/fastdfs/storage/logs/storage.log
- 若是發現日志中報的是如下信息
ERROR - file: storage_ip_changed_dealer.c, line: 180, connect to tracker server 服務器ip:22122 fail, errno: 110, error info: Connection timed out 即:鏈接超時
- 這種情況一般都是22122端口沒開放
# 開放22122端口firewall-cmd --zone=public --add-port=22122/tcp --permanent # 重啟防火墻systemctl restart firewalld.service # 當然:要是云服務器的話,直接在web管理界面中添加規則( 開放22122端口 ) 即可
2.2.3、查看默認創建的文件數
- 進入如下的目錄
cd /opt/fastdfs/storage/files/data
- 這里面有256個文件夾,而每一個文件夾里面又有256個文件夾,即256 * 256個文件夾,總的文件夾數目為6萬多個
- 這256 * 256個文件夾的作用:解決的就是如下的問題
-
- 而fastDFS就是使用那256 * 256個文件夾,把文件分別放入哪些文件夾中,這樣就讓搜索變得方便了
2.2.4、測試FastDFS
2.2.4.1、測試上傳文件
- 要想進行測試的話,需要修改一個配置文件,因為這個配置文件中的配置信息是作者余慶的
- 要修改的內容如下:
# 注意:這個目錄也要保證存在,不存在就是創建 mkdir -p /opt/fastdfs/clientbase_path=/opt/fastdfs/client tracker_server=自己服務器ip:22122
- 搞一個用來測試上傳的文件
- 執行文件上傳命令
- 可以使用如下命令看一下測試文件上傳命令是怎么寫的
- fdfs_test
- 可以使用如下命令看一下測試文件上傳命令是怎么寫的
- 提取出測試命令語法
fdfs_test <config_file> <operation> operation: upload, download, getmeta, setmeta, delete and query_servers# <> 表示必填 # 因此:在測試中,文件上傳的指令為:fdfs_test /etc/fdfs/client.conf upload /root/hello-fastdfs.txt
- 注意:防火墻的問題啊,要是報:connect to xxx.xx.xx.xx:23000 fail, errno: 113, error info: No route to host,這就是防火墻沒開放23000端口,打開就可以了
# 開放23000端口firewall-cmd --zone=public --add-port=23000/tcp --permanent # 刷新防火墻systemctl restart firewalld.service
- 上面成功之后有一堆信息,很重要
This is FastDFS client test program v5.11 Copyright (C) 2008, Happy Fish / YuQing FastDFS may be copied only under the terms of the GNU GeneralPublic License V3, which may be found in the FastDFS source kit. # 這個是說訪問fastdfs的主頁網址 - 目前還不能訪問,需要后面弄Please visit the FastDFS Home Page http://www.csource.org/ for more detail. # 這是配置的client.conf中的信息[2022-06-01 10:17:07] DEBUG - base_path=/opt/fastdfs/client, connect_timeout=30, network_timeout=60, tracker_server_count=1, anti_steal_token=0, anti_steal_secret_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0 tracker_query_storage_store_list_without_group: server 1. group_name=, ip_addr=162.14.66.60, port=23000 group_name=group1, ip_addr=162.14.66.60, port=23000storage_upload_by_filename# 重要的信息在這里group_name、remote_filename# group_name就是組名,在前面配置中見過它,就是說的文件系統 和 數據備份這二者的組合名# remote_filename 遠程文件名 這是關鍵中的關鍵,告知你:文件保存到那里去了group_name=group1, remote_filename=M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txtsource ip address: 10.0.0.16file timestamp=2022-06-01 10:17:07file size=641file crc32=1141168436# 下面這個URL地址很重要,就是去瀏覽器訪問上傳的這個文件資源的地址,但是:目前還不可以訪問,因為沒有配置Nginxexample file url: http://162.14.66.60/group1/M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txtstorage_upload_slave_by_filenamegroup_name=group1, remote_filename=M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txtsource ip address: 10.0.0.16file timestamp=2022-06-01 10:17:07file size=641file crc32=1141168436example file url: http://162.14.66.60/group1/M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt
- 單獨說明:remote_filename
remote_filename=M00/00/00/ M00 指的是:/opt/fastdfs/storage/files/data 就是前面去看默認創建文件數( 256 * 256 )的位置,跟前面的配置有關啊 00/00/ 指的就是:/opt/fastdfs/storage/files/data目錄下的00子目錄,這里面的00目錄 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt 指的是:保存的文件名 fastdfs會重新生成文件名,以防的就是同名文件,造成附件覆蓋的問題
- 上圖中幾個文件解讀
# _big 就是數據備份文件# _m 就是meta data文件,即:文件屬性文件( 文件名、文件后綴、文件大小..... )-rw-r--r-- 1 root root 641 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-rw-r--r-- 1 root root 49 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-m # 這兩個就是文件系統中的文件-rw-r--r-- 1 root root 641 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-rw-r--r-- 1 root root 49 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-m # CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt 和 文件系統中的CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt存的內容是一樣的 # CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-m 和 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-m這兩個備份文件也是相應的
2.2.4.2、測試文件下載和刪除
- 前面已經見過對應的語法了
fdfs_test <config_file> <operation> operation: upload, download, getmeta, setmeta, delete and query_servers# <> 表示必填
- 變一下就可以了
# 變成下載的命令,然后使用此命令查看完整命令即可fdfs_test /etc/fdfs/client.conf download # 根據執行上面的命令,得到文件下載的語法fdfs_test <config_file> download <group_name> <remote_filename> # 那么想要下載剛剛上傳的文件,執行如下的命令即可fdfs_test /etc/fdfs/client.conf download group1 M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt# 其中:group 和 remote_filename都在前面上傳時見過了# 注:這個下載是下載到當前所在目錄的位置 # 同理:就可以得到文件刪除的命令了fdfs_test /etc/fdfs/client.conf delete group1 M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt
- 以上這些fdfs_test只會在測試時使用,其他地方基本上都不用的
2.3、安裝Nginx
- 上傳fastdfs-niginx擴展模塊 并 解壓 - 使用官網中wiki說明的命令拉取也行
- 安裝nginx,要是有的話就跳過
- 記住兩個目錄
# nginx安裝目錄/usr/local/nginx_fdfs # fastdfs-nginx模塊的src目錄/usr/local/fastdfs-nginx-module-master/src
- 進入nginx安裝目錄,進行模塊添加配置
# 進入nginx安裝目錄cd nginx_fdfs # 執行模塊配置 # prefix 就是前面讓記住的nginx安裝目錄 add-module就是fastdfs-nginx模塊的src目錄./configure --prefix=/usr/local/nginx_fdfs --add-module=/usr/local/fastdfs-nginx-module-master/src
- 編譯并安裝
# 在安裝的nginx目錄下載執行下述命令make & make install
- 注釋事項:Nginx的安裝需要Linux安裝相關的幾個庫,否則編譯會出現錯誤,有這幾個的話就不安裝了
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel –y
2.3.1、修改需要的配置文件
- 將fastdfs-nginx擴展模塊中的mod_fastdfs.conf文件復制到/etc/fdfs中
cp /usr/local/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs
- 修改/etc/fdfs/mod_fastdfs.conf
vim mod_fastdfs.conf # 修改內容如下:# 這個目錄要保證存在,不存在就要配置好了創建它 mkdir -p /opt/fastdfs/nginx_modbase_path=/opt/fastdfs/nginx_mod tracker_server=自己服務器ip:22122 # 訪問地址是否帶上組名url_have_group_name = true store_path0=/opt/fastdfs/storage/files
- 上面base_path目錄要是不存在記得創建
- 進入nginx_fdfs的安裝目錄中,去nginx.conf中配置fastdfs-nginx的擴展模塊
# 編輯nginx.conf文件vim /usr/local/nginx_fdfs/conf/nginx.conf # 配置內容location ~ /group[1-9]/M0[0-9] { ngx_fastdfs_module; } # 解讀:ngx_fastdfs_module# 這個指令不是Nginx本身提供的,是擴展模塊提供的,根據這個指令找到FastDFS提供的Nginx模塊配置文件,然后找到Tracker,最終找到Stroager
- 啟動nginx
/usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf -t /usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf # 保險起見,查看nginx是否啟動成功ps -ef | grep nginx
- 注意:這里很容易出現啟動不起來,如果下面這個進程沒有啟動起來
nobody 3895 3894 0 15:45 ? 00:00:00 nginx: worker process
- 那么:就去查看日志文件
cd /usr/local/nginx_fdfs/logs # 還有一份日志中也可能出現錯誤信息cd /opt/fastdfs/nginx_mod
2.4、Java操作FastDFS
2.3.2、擴展模塊執行流程
- 下面這個流程很重要,涉及到另外更深入的知識( 如:集群部署FastDFS,本篇博客沒有說明集群部署,哪些就是固定命令和流程,百度復制粘貼修改即可 )
2.4.1、文件上傳
- 在resources目錄下創建fastdfs.conf文件,并編寫如下內容:
tracker_server=服務器ip:22122
- 編寫文件上傳代碼
package com.zixieqing; import org.csource.common.MyException;import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : UploadFile * @description : 該類功能 FastDFS文件上傳 * @packageName : com.zixieqing */ public class UploadFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、創建tracker客戶端 TrackerClient trackerClient = new TrackerClient(); // 3、獲取trackerServer trackerServer = trackerClient.getConnection(); // 4、獲取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、創建storage客戶端 - 這個對象就是用來上傳文件、下載文件、刪除文件的 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、上傳文件 /* 這里有兩個API需要了解 String[] upload_file(byte[] file_buff, int offset, int length, String file_ext_name, NameValuePair[] meta_list) 這個API常用來web中上傳文件的 參數1 file_buff、文件字節 offset、length、從文件的那個位置開始上傳,截止位置 參數4 file_ext_name、文件后綴 參數5 meta_list、文件的屬性文件 String[] upload_file(String local_filename, String file_ext_name, NameValuePair[] meta_list) 這個API是上傳本地文件的 參數1 local_filename、本地文件的絕對路徑 參數2 file_ext_name、文件后綴名 參數3 meta_list、文件的屬性文件,linux1中的哪個meta data,一般都不傳 上述這兩個API,注意返回值,這個String[] 很重要,就是涉及到linux中的那個組名group 和 遠程文件名remote_filename,這個group和remote_fileName一般是存在數據庫中的 */ String[] result = storageClient.upload_file("C:\Users\ZiXieQing\Desktop\圖庫\19.jpg", "jpg", null); // 7、驗證一下 for (String data : result) { System.out.println("data = " + data); } } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); } finally { // 8、釋放資源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }}
- 瀏覽器訪問
2.4.2、文件下載
- 把前面的文件上傳代碼改一下即可,換成另一個API而已
package com.zixieqing; import org.csource.common.MyException;import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : DownloadFile * @description : 該類功能 fastDFS文件下載 * @packageName : com.zixieqing */ public class DownloadFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、獲取tracker客戶端 TrackerClient trackerClient = new TrackerClient(); // 3、獲取trackerServer trackerServer = trackerClient.getConnection(); // 4、獲取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、創建storage客戶端 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、下載文件 /* 這里需要知道兩個API byte[] download_file(String group_name, String remote_filename) 這個API常用于web操作 int download_file(String group_name, String remote_filename, String local_filename) 這個API是把文件下載到本地磁盤中 這個API的返回值結果很重要 */ String group = "group1"; String remoteFileName = "M00/00/00/CgAAEGKYRg-AAIrWAAD8cA4U6dY771.jpg"; // 存入本地磁盤路徑+存入磁盤的文件名 String localFileName = "d:/靚妹.jpg"; // 只有返回值是0才表示下載成功,否則只要是其他數字都是下載失敗( 其他數字有可能是組名錯了,遠程文件名錯了........ int result = storageClient.download_file(group, remoteFileName, localFileName); // 7、驗證 System.out.println("result = " + result); } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); } finally { // 8、釋放資源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }}
2.4.3、文件刪除
package com.zixieqing; import org.csource.common.MyException;import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : DeleteFile * @description : 該類功能 FastDFS刪除文件 * @packageName : com.zixieqing */ public class DeleteFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、獲取tracker客戶端 TrackerClient trackerClient = new TrackerClient(); // 3、獲取trackerServer trackerServer = trackerClient.getConnection(); // 4、獲取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、獲取storage客戶端 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、執行文件刪除 /* int delete_file(String group_name, String remote_filename) 參數1 group_name、組名 參數2 remote_filename、遠程文件名 */ // 一樣的,返回值是0就表示成功,其他都是刪除失敗 int result = storageClient.delete_file("group", "M00/00/00/CgAAEGKYRg-AAIrWAAD8cA4U6dY771.jpg"); // 7、驗證一下 System.out.println("result = " + result); } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); }finally { // 8、釋放資源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }}
文章來自
https://www.cnblogs.com/xiegongzi/p/16330724.html