關于檔案上傳ftp伺服器問題
-
- ftp檔案上傳工具類
- 檔案上傳到伺服器
本部落格圖檔檔案是上傳到ftp伺服器上,自己在雲伺服器上搭建了一個ftp伺服器。關于怎麼搭建可以去騰訊雲官網搜尋,這裡就不講解了不然就太長了。搭建完成之後就可以做檔案上傳了。ftp檔案上傳分有建立連接配接、傳輸資料、釋放連接配接三個步驟,這裡我給出一個ftp檔案上傳的工具類
ftp檔案上傳工具類
import org.apache.commons.net.ftp.*;
import java.io.*;
import java.util.concurrent.LinkedBlockingQueue;
public class FtpUtil {
/**
* 維護FTPClient執行個體
*/
private final static LinkedBlockingQueue<FTPClient> FTP_CLIENT_QUEUE = new LinkedBlockingQueue<>();
/**
* 建立目錄
*
* @param ftpConfig 配置
* @param remotePath 需要建立目錄的目錄
* @param makePath 需要建立的目錄
* @return 是否建立成功
*/
public static boolean makeDirectory(FtpConfig ftpConfig, String remotePath, String makePath) {
try {
FTPClient ftpClient = connectClient(ftpConfig);
boolean changeResult = ftpClient.changeWorkingDirectory(remotePath);
if (!changeResult) {
throw new RuntimeException("切換目錄失敗");
}
boolean result = ftpClient.makeDirectory(makePath);
// 退出FTP
ftpClient.logout();
//歸還對象
offer(ftpClient);
return result;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 移動檔案
*
* @param ftpConfig 配置
* @param fromPath 待移動目錄
* @param fromName 待移動檔案名
* @param toPath 移動後目錄
* @param toName 移動後檔案名
* @return 是否移動成功
*/
public static boolean moveFile(FtpConfig ftpConfig, String fromPath, String fromName, String toPath, String toName) {
try {
FTPClient ftpClient = connectClient(ftpConfig);
boolean changeResult = ftpClient.changeWorkingDirectory(fromPath);
if (!changeResult) {
throw new RuntimeException("切換目錄失敗");
}
boolean result = ftpClient.rename(fromName, toPath + File.separator + toName);
// 退出FTP
ftpClient.logout();
//歸還對象
offer(ftpClient);
return result;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 删除檔案
*
* @param ftpConfig 配置
* @param remotePath 遠端目錄
* @param fileName 檔案名
* @return 是否删除成功
*/
public static boolean deleteFile(FtpConfig ftpConfig, String remotePath, String fileName) {
try {
FTPClient ftpClient = connectClient(ftpConfig);
boolean changeResult = ftpClient.changeWorkingDirectory(remotePath);
if (!changeResult) {
throw new RuntimeException("切換目錄失敗");
}
boolean result = ftpClient.deleteFile(fileName);
// 退出FTP
ftpClient.logout();
//歸還對象
offer(ftpClient);
return result;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 下載下傳檔案
*
* @param ftpConfig 配置
* @param remotePath 遠端目錄
* @param fileName 檔案名
* @param localPath 本地目錄
* @param localName 本地檔案名
* @return 是否下載下傳成功
*/
public static boolean download(FtpConfig ftpConfig, String remotePath, String fileName, String localPath, String localName) {
try {
FTPClient ftpClient = connectClient(ftpConfig);
boolean changeResult = ftpClient.changeWorkingDirectory(remotePath);
if (!changeResult) {
throw new RuntimeException("切換目錄失敗");
}
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
File file = new File(localPath, localName);
if (!file.getParentFile().exists()) {
boolean mkdirsResult = file.getParentFile().mkdirs();
if (!mkdirsResult) {
throw new RuntimeException("建立目錄失敗");
}
}
if (!file.exists()) {
boolean createFileResult = file.createNewFile();
if (!createFileResult) {
throw new RuntimeException("建立檔案失敗");
}
}
OutputStream outputStream = new FileOutputStream(file);
boolean result = ftpClient.retrieveFile(fileName, outputStream);
outputStream.flush();
outputStream.close();
// 退出FTP
ftpClient.logout();
//歸還對象
offer(ftpClient);
return result;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 上傳檔案
*
* @param ftpConfig 配置
* @param remotePath 遠端目錄
* @param inputStream 待上傳檔案輸入流
* @param fileName 檔案名
* @return 是否上傳成功
*/
public static boolean upload(FtpConfig ftpConfig, String remotePath, InputStream inputStream, String fileName) {
try {
FTPClient ftpClient = connectClient(ftpConfig);
boolean changeResult = ftpClient.changeWorkingDirectory(remotePath);
if (!changeResult) {
throw new RuntimeException("切換目錄失敗");
}
// 設定被動模式
ftpClient.enterLocalPassiveMode();
// 設定流上傳方式
ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
// 設定二進制上傳
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//中文存在問題
// 上傳 fileName為上傳後的檔案名
boolean result = ftpClient.storeFile(fileName, inputStream);
// 關閉本地檔案流
inputStream.close();
// 退出FTP
ftpClient.logout();
//歸還對象
offer(ftpClient);
return result;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 登入ftp
*
* @param ftpConfig 配置
* @return 是否登入成功
* @throws IOException
*/
private static FTPClient connectClient(FtpConfig ftpConfig) throws IOException {
FTPClient ftpClient = getClient();
// 連接配接FTP伺服器
ftpClient.connect(ftpConfig.ip, ftpConfig.port);
// 登入FTP
ftpClient.login(ftpConfig.userName, ftpConfig.password);
// 正常傳回230登陸成功
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
throw new RuntimeException("連接配接ftp失敗");
}
ftpClient.setControlEncoding("GBK");
return ftpClient;
}
/**
* 擷取ftpClient對象
*
* @return 擷取client對象
*/
private static FTPClient getClient() {
FTPClient ftpClient = FTP_CLIENT_QUEUE.poll();
if (ftpClient != null) {
return ftpClient;
}
return new FTPClient();
}
private static void offer(FTPClient ftpClient) {
FTP_CLIENT_QUEUE.offer(ftpClient);
}
/**
* 連接配接ftp配置
*/
public static class FtpConfig {
private String ip;
private int port;
private String userName;
private String password;
public FtpConfig setIp(String ip) {
this.ip = ip;
return this;
}
public FtpConfig setPort(int port) {
this.port = port;
return this;
}
public FtpConfig setUserName(String userName) {
this.userName = userName;
return this;
}
public FtpConfig setPassword(String password) {
this.password = password;
return this;
}
}
}
将工具類放到項目中,然後就可以開始編寫檔案上傳代碼啦。
檔案上傳到伺服器
if (file != null && !file.isEmpty()) {
String olderName = file.getOriginalFilename();
String suffix = FilenameUtils.getExtension(olderName);
if (suffix.equalsIgnoreCase("jpg") || suffix.equalsIgnoreCase("png") || suffix.equalsIgnoreCase("gif")) {
String newName = UUID.randomUUID().toString().replace("-", "").substring(15).toLowerCase() + "." + suffix;
FtpUtil.FtpConfig ftpConfig = new FtpUtil.FtpConfig();
ftpConfig.setIp("xxx.xxx.xxx.xxx");//ip位址
ftpConfig.setPort(21);//端口号,預設是21
ftpConfig.setUserName("ftpuser");//帳号,預設是ftpuser
ftpConfig.setPassword("xxxxxx");//密碼
try {
//上傳圖檔
FtpUtil.upload(ftpConfig, "/myblog/", file.getInputStream(), newName);
String fileName = user.getAvatar();
if (fileName != null) {
String str = "default.jpg";
if (!str.equals(fileName)) {
//删除原圖檔
FtpUtil.deleteFile(ftpConfig, "/myblog/", fileName);
}
}
} catch (IOException e) {
e.printStackTrace();
}
user.setAvatar(newName);
} else {
return new BtoResult<>(false,"圖檔格式不對");
}
}else {
user.setAvatar("default.jpg");
}
注意:我的後端接受檔案用的是MultipartFile接受
最後,ftp檔案上傳就完成啦。
原文連結(釋出位址):https://xiejiabin.online/blog.html?blogId=202007010011