zoukankan      html  css  js  c++  java
  • ftp上传与下载文件

    准备工作

    服务器已经配置好ftp服务

    服务器linux centos 7.4 搭建ftp服务器:https://www.cnblogs.com/mmzs/p/10601683.html

    需要用到的jar包:

    <dependency>
    	<groupId>commons-net</groupId>
    	<artifactId>commons-net</artifactId>
    	<version>3.3</version>
    </dependency>
    

    配置文件

    • application.yml
    # 配置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
    
    • FtpConfig配置信息类
    @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;
    	
    }
    

    工具类FtpUtil内容

    @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: 下载成功

    代码 github 地址:https://github.com/mmzsblog/springboot-FtpUtil

  • 相关阅读:
    一些特殊的矩阵快速幂 hdu5950 hdu3369 hdu 3483
    HDU
    UVA-796 Critical Links 找桥
    HDU 4612 Warm up
    2017 ICPC乌鲁木齐 A Coins 概率dp
    HDU6223 Infinite Fraction Path bfs+剪枝
    Java基础知识学习(一)
    算法(一)
    面试题整理:SQL(二)
    面试题整理:SQL(一)
  • 原文地址:https://www.cnblogs.com/mmzs/p/10606498.html
Copyright © 2011-2022 走看看