天天看點

關于檔案上傳ftp伺服器問題

關于檔案上傳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