1、文件上傳簡單流程分析圖: 2、Fastdfs介紹: Fastdfs由兩個角色組成: Tracker(集群):調度(幫你找到有空閑的Storage) Storage(集群):文件存儲(幫你保存文件或獲取需要的文件) 流程: 1.Storage和tracker 發送心跳連接。 2.客戶端請求trac ...
1、文件上傳簡單流程分析圖:
2、Fastdfs介紹:
Fastdfs由兩個角色組成:
Tracker(集群):調度(幫你找到有空閑的Storage)
Storage(集群):文件存儲(幫你保存文件或獲取需要的文件)
流程:
1.Storage和tracker 發送心跳連接。
2.客戶端請求tracker,tracker調度一個Storage,返回Storage的ip和埠。
3.客戶端請求Storage,上傳文件。
4.Storage保存文件,生成file_id,並返回。
5.客戶端接收到file_id並保存。
3、上傳下載流程圖:
上傳:
下載:
4、Fastdfs上傳具體實現步驟:
1. 在伺服器上搭建好fastdfs環境:這個由運維人員操作,開發人員無需關心。
2. 在本地maven倉庫導入fastdfs的jar包(該jar包在maven中央倉庫中沒有,無法通過idea自動下載,只能手動導入到本地倉庫中去)
jar包下載地址(fastdfs_client_v1.20.jar):https://sourceforge.net/projects/fastdfs/files/Java%20Client%20API%20Library/Java%20Client%20Library%20V1.20%20%28compiled%20by%20JDK%201.6%29/fastdfs_client_v1.20.jar/download?use_mirror=liquidtelecom&download=&failedmirror=jaist.dl.sourceforge.net
導入本地倉庫:
在jar包所在的目錄打開cmd,然後輸入以下命令,執行後即可在maven本地倉庫導入jar包併在cmd顯示出jar包在倉庫中的路徑。
mvn install:install-file -DgroupId=org.csource.fastdfs -DartifactId=fastdfs -Dversion=1.2 -Dpackaging=jar -Dfile= fastdfs_client_v1.20.jar |
3. 項目中引入
<dependency> <groupId>org.csource.fastdfs</groupId> <artifactId>fastdfs</artifactId> <version>1.2</version> </dependency>
4、項目中引入以下工具類:
fdfs_client.conf 文件(用於保存指向 tracker 的IP+埠(預設)):
tracker_server=172.16.2.274:22122
工具類:
import org.csource.common.NameValuePair; import org.csource.fastdfs.ClientGlobal; import org.csource.fastdfs.StorageClient; import org.csource.fastdfs.StorageServer; import org.csource.fastdfs.TrackerClient; import org.csource.fastdfs.TrackerServer; public class FastDfsApiOpr { public static String CONF_FILENAME = FastDfsApiOpr.class.getResource("/fdfs_client.conf").getFile(); /** * 上傳文件 * @param file * @param extName * @return */ public static String upload(byte[] file,String extName) { try { ClientGlobal.init(CONF_FILENAME); TrackerClient tracker = new TrackerClient(); TrackerServer trackerServer = tracker.getConnection(); StorageServer storageServer = null; StorageClient storageClient = new StorageClient(trackerServer, storageServer); NameValuePair nvp [] = new NameValuePair[]{ new NameValuePair("age", "18"), new NameValuePair("sex", "male") }; String fileIds[] = storageClient.upload_file(file,extName,nvp); System.out.println(fileIds.length); System.out.println("組名:" + fileIds[0]); System.out.println("路徑: " + fileIds[1]); return "/"+fileIds[0]+"/"+fileIds[1]; } catch (Exception e) { e.printStackTrace(); return null; } } /** * 下載文件 * @param groupName * @param fileName * @return */ public static byte[] download(String groupName,String fileName) { 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(groupName, fileName); return b; } catch (Exception e) { e.printStackTrace(); return null; } } // @Test // 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(); // } // } // @Test // 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(); // } // } /** * 刪除文件 * @param groupName * @param fileName */ public static void delete(String groupName,String fileName){ 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(groupName,fileName); System.out.println( i==0 ? "刪除成功" : "刪除失敗:"+i); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("刪除異常,"+e.getMessage()); } } }
5、在contorller中使用:
@RestController public class FileController { /** * 文件上傳 MultipartFile 是SpringMVC封裝好的API方便操作上傳的文件的 * @param file * @return */ @PostMapping("/fastdfs") public AjaxResult upload(MultipartFile file){ try { //獲取文件的擴展名 String filename = file.getOriginalFilename(); String extName = filename.substring(filename.lastIndexOf(".")+1); String file_id = FastDfsApiOpr.upload(file.getBytes(), extName); return AjaxResult.me().setSuccess(true).setMessage("上傳成功!").setRestObj(file_id); } catch (Exception e) { e.printStackTrace(); return AjaxResult.me().setSuccess(false).setMessage("上傳失敗!"+e.getMessage()); } } /** * 刪除文件 * @param file_id * @return */ @DeleteMapping("/fastdfs") public AjaxResult delete(String file_id){ try { // /group1/M00/00/01/rBACgF1euQiAEdrcAACbjnUEnrE193.jpg file_id = file_id.substring(1);// group1/M00/00/01/rBACgF1euQiAEdrcAACbjnUEnrE193.jpg String groupName = file_id.substring(0, file_id.indexOf("/")); String fileName = file_id.substring(file_id.indexOf("/")+1); FastDfsApiOpr.delete(groupName, fileName); return AjaxResult.me().setSuccess(true).setMessage("刪除成功!"); } catch (Exception e) { e.printStackTrace(); return AjaxResult.me().setSuccess(false).setMessage("刪除失敗!"); } } }
5.1控制文件上傳的大小
為瞭解決有些文件因大於預設上傳文件大小的而無法上傳的問題,可以在網關模塊和引用Fastdfs的controller所在的模塊的啟動類上加上如下代碼:
/** * 文件大小上傳配置 * @return */ @Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); //單個文件最大 factory.setMaxFileSize("10240KB"); //KB,MB /// 設置總上傳數據總大小 factory.setMaxRequestSize("102400KB"); return factory.createMultipartConfig(); }
6、前端頁面代碼
<el-form-item label="logo"> <el-upload class="upload-demo" action="http://localhost:6001/services/common/fastdfs" :file-list="addForm.logoList" list-type="picture" :on-success="logoUploadSuccess" :before-upload="handleBeforeUpload" :on-remove="handleLogoRemove"> <el-button size="small" type="primary">點擊上傳</el-button> </el-upload> </el-form-item>
methods: {
handleLogoRemove(file, fileList){
//file 刪除的文件
//調用刪除文件的介面
let file_id = file.response.restObj
this.$http.delete("/common/fastdfs?file_id="+file_id)
.then(res=>{
let {success,message,restObj} = res.data;
if(success){
//fileList 刪除後的文件列表
this.addForm.logoList = fileList;
}else{
this.$message({
message:message,
type:"error"
})
}
})
},
//圖片上傳之前的回調
handleBeforeUpload(file){
if(this.addForm.logoList.length>0){
this.$message({
message:"只能上傳一張圖片!",
type:"warning"
})
return false;
}
},
//圖片上傳成功的回調
logoUploadSuccess(response, file, fileList){
//fileList = [{response:{success:true,restObj:''}},file,file]
this.addForm.logoList = fileList;
console.log(response)
}
}