服務器linux centos 7.4 搭建ftp服務器:http://www.javashuo.com/article/p-mudyluny-kt.htmlhtml
<dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.3</version> </dependency>
# 配置ftp服務器信息 ftp: # ftp服務器的IP地址 url: 127.0.0.0 # 默認端口是21 port: 21 username: ftpuser password: ftpuser # ftp服務器存放文件的路徑 remotePath: /data/ftp # 本地須要上傳的文件的路徑 localDir: D:/test # ftp上文件下載到本地存放的路徑 downDir: D:/test
@Getter @Component public class FtpConfig { /** * ftp服務器地址 */ @Value("${ftp.url}") private String url; /** * ftp服務器端口 */ @Value("${ftp.port}") private int port; /** * ftp服務器用戶名 */ @Value("${ftp.username}") private String username; /** * ftp服務器密碼 */ @Value("${ftp.password}") private String password; /** * ftp服務器存放文件的路徑 */ @Value("${ftp.remotePath}") private String remotePath; /** * 本地須要上傳的文件的路徑 */ @Value("${ftp.localDir}") private String localDir; /** * 下載文件時,存放在本地的路徑 */ @Value("${ftp.downDir}") private String downDir; }
@Slf4j(topic="文件上傳/下載===ftp服務器:") public class FtpUtil { private static FTPClient mFTPClient = new FTPClient(); private static FtpUtil ftp = new FtpUtil(); public FtpUtil() { // 在控制檯打印操做過程 mFTPClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); } /** * 上傳文件到ftp服務器 */ public static boolean ftpUpload(String fileName, String ftpUrl, int ftpPort, String ftpUsername, String ftpPassword, String ftpLocalDir, String ftpRemotePath) { boolean result = false; try { boolean isConnection = ftp.openConnection(ftpUrl, ftpPort, ftpUsername, ftpPassword); if (isConnection) { boolean isSuccess = ftp.upload(ftpRemotePath, ftpLocalDir + "/" + fileName); if (isSuccess) { log.info("文件上傳成功!"); result = true; } else { log.info("文件上傳失敗!"); result = false; } ftp.logout(); } else { log.info("連接ftp服務器失敗,請檢查配置信息是否正確!"); result = false; } } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } /** * 從ftp服務器下載文件到本地 */ public static boolean ftpDownload(String fileName, String ftpUrl, int ftpPort, String ftpUsername, String ftpPassword, String ftpRemotePath, String ftpDownDir) { boolean result = false; try { boolean isConnection = ftp.openConnection(ftpUrl, ftpPort, ftpUsername, ftpPassword); if (isConnection) { boolean isDownloadOk = ftp.downLoad(fileName, ftpDownDir); boolean isCreateOk = ftp.createDirectory(ftpRemotePath, ftp.mFTPClient); if (isDownloadOk && isCreateOk) { log.info("文件下載成功!"); result = true; } else { log.info("文件下載失敗!"); result = false; } ftp.logout(); } else { log.info("連接ftp服務器失敗,請檢查配置信息是否正確!"); result = false; } } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } /** * 鏈接ftp服務器 * * @param host * ip地址 * @param port * 端口號 * @param account * 帳號 * @param pwd * 密碼 * @return 是否鏈接成功 * @throws SocketException * @throws IOException */ private boolean openConnection(String host, int port, String account, String pwd) throws SocketException, IOException { mFTPClient.setControlEncoding("UTF-8"); mFTPClient.connect(host, port); if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) { mFTPClient.login(account, pwd); if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) { System.err.println(mFTPClient.getSystemType()); FTPClientConfig config = new FTPClientConfig(mFTPClient.getSystemType().split(" ")[0]); config.setServerLanguageCode("zh"); mFTPClient.configure(config); return true; } } disConnection(); return false; } /** * 登出並斷開鏈接 */ public void logout() { System.err.println("logout"); if (mFTPClient.isConnected()) { System.err.println("logout"); try { mFTPClient.logout(); disConnection(); } catch (IOException e) { e.printStackTrace(); } } } /** * 斷開鏈接 */ private void disConnection() { if (mFTPClient.isConnected()) { try { mFTPClient.disconnect(); } catch (IOException e) { e.printStackTrace(); } } } /** * 下載文件到本地地址 * * @param remotePath * 遠程地址 * @param loacal * 本地地址 * @throws IOException */ public boolean downLoad(String remotePath, String localDir) throws IOException { // 進入被動模式 mFTPClient.enterLocalPassiveMode(); // 以二進制進行傳輸數據 mFTPClient.setFileType(FTP.BINARY_FILE_TYPE); FTPFile[] ftpFiles = mFTPClient.listFiles(remotePath); if (ftpFiles == null || ftpFiles.length == 0) { log.info("遠程文件不存在"); return false; } else if (ftpFiles.length > 1) { log.info("遠程文件是文件夾"); return false; } long lRemoteSize = ftpFiles[0].getSize(); // 本地文件的地址 File localFileDir = new File(localDir); if (!localFileDir.exists()) { localFileDir.mkdirs(); } File localFile = new File(localFileDir, ftpFiles[0].getName()); long localSize = 0; FileOutputStream fos = null; if (localFile.exists()) { if (localFile.length() == lRemoteSize) { System.err.println("已經下載完畢"); return true; } else if (localFile.length() < lRemoteSize) { // 要下載的文件存在,進行斷點續傳 localSize = localFile.length(); mFTPClient.setRestartOffset(localSize); fos = new FileOutputStream(localFile, true); } } if (fos == null) { fos = new FileOutputStream(localFile); } InputStream is = mFTPClient.retrieveFileStream(remotePath); byte[] buffers = new byte[1024]; long step = lRemoteSize / 10; long process = localSize / step; int len = -1; while ((len = is.read(buffers)) != -1) { fos.write(buffers, 0, len); localSize += len; long newProcess = localSize / step; if (newProcess > process) { process = newProcess; System.err.println("下載進度:" + process); } } is.close(); fos.close(); boolean isDo = mFTPClient.completePendingCommand(); if (isDo) { System.err.println("下載成功"); } else { System.err.println("下載失敗"); } return isDo; } /** * 建立遠程目錄 * * @param remote * 遠程目錄 * @param ftpClient * ftp客戶端 * @return 是否建立成功 * @throws IOException */ public boolean createDirectory(String remote, FTPClient ftpClient) throws IOException { String dirctory = remote.substring(0, remote.lastIndexOf("/") + 1); if (!dirctory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(dirctory)) { int start = 0; int end = 0; if (dirctory.startsWith("/")) { start = 1; } end = dirctory.indexOf("/", start); while (true) { String subDirctory = remote.substring(start, end); if (!ftpClient.changeWorkingDirectory(subDirctory)) { if (ftpClient.makeDirectory(subDirctory)) { ftpClient.changeWorkingDirectory(subDirctory); } else { System.err.println("建立目錄失敗"); return false; } } start = end + 1; end = dirctory.indexOf("/", start); if (end <= start) { break; } } } return true; } /** * 上傳的文件 * * @param remotePath * 上傳文件的路徑地址(文件夾地址) * @param localPath * 本地文件的地址 * @throws IOException * 異常 */ public boolean upload(String remotePath, String localPath) throws IOException { // 進入被動模式 mFTPClient.enterLocalPassiveMode(); // 以二進制進行傳輸數據 mFTPClient.setFileType(FTP.BINARY_FILE_TYPE); File localFile = new File(localPath); if (!localFile.exists()) { System.err.println("本地文件不存在"); return false; } String fileName = localFile.getName(); if (remotePath.contains("/")) { boolean isCreateOk = createDirectory(remotePath, mFTPClient); if (!isCreateOk) { System.err.println("文件夾建立失敗"); return false; } } // 列出ftp服務器上的文件 FTPFile[] ftpFiles = mFTPClient.listFiles(remotePath); long remoteSize = 0l; String remoteFilePath = remotePath + "/" + fileName; if (ftpFiles.length > 0) { FTPFile mFtpFile = null; for (FTPFile ftpFile : ftpFiles) { if (ftpFile.getName().endsWith(fileName)) { mFtpFile = ftpFile; break; } } if (mFtpFile != null) { remoteSize = mFtpFile.getSize(); if (remoteSize == localFile.length()) { System.err.println("文件已經上傳成功"); return true; } if (remoteSize > localFile.length()) { if (!mFTPClient.deleteFile(remoteFilePath)) { System.err.println("服務端文件操做失敗"); } else { boolean isUpload = uploadFile(remoteFilePath, localFile, 0); System.err.println("是否上傳成功:" + isUpload); } return true; } if (!uploadFile(remoteFilePath, localFile, remoteSize)) { System.err.println("文件上傳成功"); return true; } else { // 斷點續傳失敗刪除文件,從新上傳 if (!mFTPClient.deleteFile(remoteFilePath)) { System.err.println("服務端文件操做失敗"); } else { boolean isUpload = uploadFile(remoteFilePath, localFile, 0); System.err.println("是否上傳成功:" + isUpload); } return true; } } } boolean isUpload = uploadFile(remoteFilePath, localFile, remoteSize); System.err.println("是否上傳成功:" + isUpload); return isUpload; } /** * 上傳文件 * * @param remoteFile * 包含文件名的地址 * @param localFile * 本地文件 * @param remoteSize * 服務端已經存在的文件大小 * @return 是否上傳成功 * @throws IOException */ private boolean uploadFile(String remoteFile, File localFile, long remoteSize) throws IOException { long step = localFile.length() / 10; long process = 0; long readByteSize = 0; RandomAccessFile randomAccessFile = new RandomAccessFile(localFile, "r"); OutputStream os = mFTPClient.appendFileStream(remoteFile); if (remoteSize > 0) { // 已經上傳一部分的時候就要進行斷點續傳 process = remoteSize / step; readByteSize = remoteSize; randomAccessFile.seek(remoteSize); mFTPClient.setRestartOffset(remoteSize); } byte[] buffers = new byte[1024]; int len = -1; while ((len = randomAccessFile.read(buffers)) != -1) { os.write(buffers, 0, len); readByteSize += len; long newProcess = readByteSize / step; if (newProcess > process) { process = newProcess; System.err.println("當前上傳進度爲:" + process); } } os.flush(); randomAccessFile.close(); os.close(); boolean result = mFTPClient.completePendingCommand(); return result; } }
@RestController @RequestMapping(value = "/ftp") @Slf4j(topic="請求ftp服務器") public class FtpController { @Autowired FtpConfig ftpConfig; @GetMapping("/upload") public String upload() { String fileName = "uploadfile.txt"; boolean result = FtpUtil.ftpUpload(fileName, ftpConfig.getUrl(),ftpConfig.getPort(),ftpConfig.getUsername(), ftpConfig.getPassword(), ftpConfig.getLocalDir(), ftpConfig.getRemotePath()); if (result) { log.info("=======上傳文件"+ fileName +"成功======="); } else { log.info("=======上傳文件"+ fileName +"失敗======="); } return result?"上傳成功":"上傳失敗"; } @GetMapping("/download") public String download(){ String fileName = "welcome.txt"; boolean result = FtpUtil.ftpDownload(fileName, ftpConfig.getUrl(),ftpConfig.getPort(),ftpConfig.getUsername(), ftpConfig.getPassword(), ftpConfig.getRemotePath(), ftpConfig.getLocalDir() ); if (result) { log.info("=======下載文件"+ fileName +"成功======="); } else { log.info("=======下載文件"+ fileName +"失敗======="); } return result?"下載成功":"下載失敗"; } }
測試結果1: 上傳成功
測試結果2: 下載成功java
代碼 github 地址:https://github.com/mmzsblog/springboot-FtpUtil
linux