文件传输协议(File Transfer Protocol,FTP),基于该协议FTP客户端与服务端可以实现共享文件、上传文件、下载文件。
FTP 基于TCP协议生成一个虚拟的连接,主要用于控制FTP连接信息,同时再生成一个单独的TCP连接用于FTP数据传输。用户可以通过客户端向FTP服务器端上传、下载、删除文件,FTP服务器端可以同时提供给多人共享使用。
FTP服务是Client/Server(简称C/S)模式,基于FTP协议实现FTP文件对外共享及传输的软件称之为FTP服务器源端,客户端程序基于FTP协议,则称之为FTP客户端,FTP客户端可以向FTP服务器上传、下载文件
java
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
public class FtpUtil {
	private static final Logger logger = LoggerFactory.getLogger(FtpUtil.class);
	private String url;
	private String port;
	private String username;
	private String password;
	private String dir;
	private String config = "";
	private static String OS = System.getProperty("os.name").toLowerCase();
	private FTPClient ftpClient;
	public String getUrl() {
		return url;
	}
	public String getPort() {
		return port;
	}
	public FtpUtil() {
		ftpClient = new FTPClient();
		ftpClient.setBufferSize(1024);
		ftpClient.setControlEncoding("UTF-8");
		ftpClient.setDefaultTimeout(300000);
		ftpClient.setConnectTimeout(300000);
		ftpClient.setDataTimeout(300000);
		ftpClient.configure(getClientConfig());
	}
	public void getConn(String ftpConfig) {
		if (config.equals(ftpConfig)) {
			return;
		}
		System.out.println("reading FTP Config...");
		try {
			if (ftpConfig.indexOf("/", ftpConfig.indexOf("@")) == -1) {
				dir = "";
				port = ftpConfig.substring(ftpConfig.indexOf(":", ftpConfig.indexOf("@")) + 1);
			} else {
				dir = ftpConfig.substring(ftpConfig.indexOf("/", ftpConfig.indexOf("@")) + 1);
				port = ftpConfig.substring(ftpConfig.indexOf(":", ftpConfig.indexOf("@")) + 1, ftpConfig.indexOf("/", ftpConfig.indexOf("@")));
			}
			url = ftpConfig.substring(ftpConfig.indexOf("@") + 1, ftpConfig.indexOf(":", ftpConfig.indexOf("@") - 1));
			username = ftpConfig.substring(ftpConfig.indexOf("//") + 2, ftpConfig.indexOf(":", ftpConfig.indexOf("//")));
			password = ftpConfig.substring(ftpConfig.indexOf(":", ftpConfig.indexOf("//")) + 1, ftpConfig.indexOf("@"));
		} catch (Exception e) {
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(), "FTP系统参数配置出错");
		}
		if ("".equals(dir)) {
			config = "ftp://" + username + ":" + password + "@" + url + ":" + port;
		} else {
			config = "ftp://" + username + ":" + password + "@" + url + ":" + port + "/" + dir;
		}
		System.out.println(config);
	}
	private void ftpConnect(String url, String port, String username, String password) {
		System.out.println("连接" + config);
		try {
			ftpClient.connect(url, Integer.parseInt(port));
			boolean loginResult = ftpClient.login(username, password);
			int returnCode = ftpClient.getReplyCode();
			if (loginResult && FTPReply.isPositiveCompletion(returnCode)) {
				System.out.println("ftp连接成功");
			} else {
				throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"FTP连接失败");
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"FTP客户端出错或已关闭!"+ e.toString());
		}
	}
	public void ftpDisconnect() {
		try {
			if (ftpClient.isConnected()) {
				ftpClient.logout();
				ftpClient.disconnect();
				System.out.println("关闭ftp连接");
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"关闭FTP连接发生异常!");
		}
	}
	public boolean fileExist(String remotePath, String fileName) {
		if (!ftpClient.isConnected()) {
			ftpConnect(url, port, username, password);
		}
		try {
			//新方法
			boolean b = ftpClient.changeWorkingDirectory(remotePath);
			ftpClient.enterLocalPassiveMode(); // Use passive mode as default
			String[] nameList = ftpClient.listNames();
			for (String s : nameList) {
				if (s.equals(fileName)) {
					return true;
				}
			}
			logger.info("读取文件信息不存在:"+remotePath +"/"+fileName);
			return false;
		} catch (NullPointerException e) {
			e.printStackTrace();
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"文件不存在!" );
		} catch (IOException e) {
			e.printStackTrace();
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"FTP文件读取发生异常!");
		} finally {
			ftpDisconnect();
		}
	}
	public boolean fileUpload(String remotePath, String fileName, InputStream fis) {
		if (!ftpClient.isConnected()) {
			ftpConnect(url, port, username, password);
		}
		try {
			System.out.println("上传'" + fileName + "'到" + remotePath);
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftpClient.makeDirectory(dir + remotePath);
			ftpClient.changeWorkingDirectory(dir + remotePath);
			ftpClient.enterLocalPassiveMode();
			System.out.println("uploading...");
			boolean returnMessage = ftpClient.storeFile(fileName, fis);
			if (returnMessage) {
				System.out.println("上传成功...");
			}
			return returnMessage;
		} catch (IOException e) {
			e.printStackTrace();
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"FTP文件上传发生异常!");
		} finally {
			IOUtils.closeQuietly(fis);
		}
	}
	public boolean fileRename(String path, String oldName, String newName) {
		if (!ftpClient.isConnected()) {
			ftpConnect(url, port, username, password);
		}
		try {
			System.out.println("文件重命名");
			ftpClient.changeWorkingDirectory(dir + path);
			ftpClient.enterLocalPassiveMode();
			return ftpClient.rename(oldName, newName);
		} catch (IOException e) {
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"FTP文件重命名发生异常!");
		}
	}
	public boolean fileDelete(String pathName) {
		if (!ftpClient.isConnected()) {
			ftpConnect(url, port, username, password);
		}
		try {
			System.out.println("删除" + pathName);
			ftpClient.enterLocalPassiveMode();
			boolean returnMessage = ftpClient.deleteFile(dir + pathName);
			if (returnMessage) {
				System.out.println("删除成功!");
			}
			return returnMessage;
		} catch (IOException e) {
			e.printStackTrace();
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"FTP文件删除发生异常!");
		}
	}
	public ByteArrayOutputStream fileGet(String path, String fileName) {
		if (!ftpClient.isConnected()) {
			ftpConnect(url, port, username, password);
		}
		try {
			ftpClient.setControlEncoding("GBK");
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftpClient.changeWorkingDirectory(dir + path);
			ftpClient.enterLocalPassiveMode();
			System.out.println("读取文件信息:" + path + "/" + fileName);
			InputStream ins = ftpClient.retrieveFileStream(fileName);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len;
			while ((len = ins.read(buffer)) > -1) {
				baos.write(buffer, 0, len);
			}
			baos.flush();
			ins.close();
			System.out.println("文件读取完成");
			return baos;
		} catch (NullPointerException e) {
			e.printStackTrace();
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"文件不存在!");
		} catch (IOException e) {
			e.printStackTrace();
			throw new BusinessException(ResultCodeEnum.ERR_0x1002.getCode(),"FTP文件读取发生异常!");
		} finally {
			ftpDisconnect();
		}
	}
	private static FTPClientConfig getClientConfig() {
		String sysType = null;
		if (isLinux()) {
			sysType = FTPClientConfig.SYST_UNIX;
		} else if (isWindows()) {
			sysType = FTPClientConfig.SYST_NT;
		}
		FTPClientConfig config = new FTPClientConfig(sysType);
		config.setRecentDateFormatStr("yyyy-MM-dd HH:mm");
		return config;
	}
	private static boolean isLinux() {
		return OS.contains("linux");
	}
	private static boolean isWindows() {
		return OS.contains("windows");
	}
	public static String convertStreamToString(InputStream is, String encoding) {
		ByteArrayOutputStream bao = null;
		String result = "";
		try {
			bao = new ByteArrayOutputStream();
			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = is.read(buf)) != -1) {
				bao.write(buf, 0, len);
			}
			result = new String(bao.toByteArray(), encoding);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	public String getMedDocPath(String patientId, String visitId) {
		if (patientId.length() <= 10) {
			patientId = StringUtils.rightPad(patientId, 9, "0") + patientId.length();
		} else {
			patientId = StringUtils.leftPad(patientId, 10, "0");
		}
		StringBuilder newPatientId = new StringBuilder();
		try {
			byte[] bytes = patientId.getBytes(StandardCharsets.US_ASCII);
			for (byte bt : bytes) {
				String ascii = "";
				int asciiLength = (int) bt % 10;
				ascii = Integer.toString(asciiLength);
				newPatientId.append(ascii);
			}
			patientId = newPatientId.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		StringBuilder ftpPath = new StringBuilder("/MEDDOC");
		for (int i = 0; i < 10; i += 2) {
			ftpPath.append("/");
			ftpPath.append(patientId, i, i + 2);
		}
		ftpPath.append("/").append("IP").append("_").append(visitId);
		return ftpPath.toString();
	}
}
本文作者:Weee
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!