前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >FTP上传文件,Apache篇

FTP上传文件,Apache篇

作者头像
高爽
发布2022-05-07 15:25:06
4.3K0
发布2022-05-07 15:25:06
举报
文章被收录于专栏:高爽的专栏

        前段时间做了个任务,是公司liunx机器上有个公司静态网站的文件夹,因为不定期的修改,修改完之后要同步到FTP服务器上,之前一直是手动使用FTP工具来同步,我的任务是开发一个能够同步静态网站的action,集成到ETL工具中,然后每天会自动运行这个action,这样就避免手动同步了。

        之前没有做过FTP上传,百度之,做FTP上传有两个类库,一个sun的FtpClient,不过sun是不推荐使用这个类库的,而且引入的时候要指定rule,另一个是Apache的FTPClient,我先使用了sun的,出现了一些问题,没有找到解决方案,本文主要说明的是使用Apache的工具类,关于sun的FtpClient,会在下一篇文章中说明。

        其实主要就是干4个事情:

        1. 初始化参数

        2. 连接ftp

        3. 拷贝文件,有可能是递归,因为文件夹下包含目录

        4. 断开ftp连接

        每次同步只是同步更新文件,所以我把同步时间记录在一个文件里,放在本地,上传文件的时候判断该文件的更新时间是否大于上次的同步时间。

还有就是FTPClient的storeFile()方法,需要两个参数,一个是文件名,另一个是输入流,这样我就无法控制它的缓冲区大小,拷入源码追踪了一个,它的缓冲区字节是在Utils中定义的,默认是1024,我给它改成了1024 × 64的,然后重新编译回去。

        还有一个方法是storeFileStream()方法,它会返回一个OutputStream,不过如果该文件不存在的话,返回的是null,我没有找到创建文件的方式,很遗憾。

        下面贴代码,主要看copyDirectory方法。

代码语言:javascript
复制
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTPClient;

/**
 * 向ftp同步静态网站(ftp上传)
 * @author gaoshuang
 *
 */
public class SynchronizeWebsiteAction implements IETLAction {
	/**
	 * 同步文件计数
	 */
	private int num;
	/**
	 * 本地文件路径
	 */
	private String localPath;
	/**
	 * ftp地址
	 */
	private String ipAdress;
	/**
	 * 用户名
	 */
	private String username;
	/**
	 * 密码
	 */
	private String password;
	/**
	 * ftp文件路径
	 */
	private String ftpPath;
	/**
	 * 上次更新时间
	 */
	private long lastUpdate;
	/**
	 * ftp连接
	 */
	private FTPClient ftp;
	
	public void addAdapter(String name, int type, ISourceAdapter adapter,
			String description) {
	}
	
	/**
	 * 入口方法
	 */
	public void execute(String params, ETLContext context) throws Exception {
		init(params);
		connect();
		copyDirectory(localPath, ftpPath);
		disConnect();
		// 记录本次更新时间
		OutputStream os = new FileOutputStream(localPath + "/lastUpdate.txt");
		os.write((System.currentTimeMillis() + "").getBytes());
	}
	
	/**
	 * 初始化
	 * @param params action参数
	 * @throws NumberFormatException
	 * @throws IOException
	 */
	private void init(String params) throws NumberFormatException, IOException {
		String[] paths = params.split(",");
		localPath = paths[0];
		String[] ftpInfo = paths[1].split(";");
		ipAdress = ftpInfo[0];
		username = ftpInfo[1];
		password = ftpInfo[2];
		ftpPath = ftpInfo[3];
		lastUpdate = getLastUpdate();
	}
	
	/**
	 * 得到上次更新时间
	 * @return
	 * @throws NumberFormatException
	 * @throws IOException
	 */
	private long getLastUpdate() throws NumberFormatException, IOException {
		File file = new File(localPath + "/lastUpdate.txt");
		long time = 0;
		if(file.exists()) {
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
			time = Long.parseLong(br.readLine());
		}
		return time;
	}

	/**
	 * 拷贝目录
	 * @param srcDirectoryPath 源
	 * @param destDirectoryPath 目标
	 * @throws IOException 
	 */
	public void copyDirectory(String srcDirectoryPath, String destDirectoryPath) throws IOException {
		// 创建不存在的目录
		reConnect();
		ftp.makeDirectory(destDirectoryPath);
		File src = new File(srcDirectoryPath);
		File[] allFile = src.listFiles(); // 取得当前文件夹下的所有文件,包括目录
		String srcName = "";
		// 拷貝文件
		for (int currentFile = 0; currentFile < allFile.length; currentFile++) {
			if (!allFile[currentFile].isDirectory()) {
				// 如果是文件是采用处理文件的方式
				srcName = allFile[currentFile].toString();
				Logger.debug("开始上传文件到" + destDirectoryPath + "/" + allFile[currentFile].getName());
				copyFile(srcName, destDirectoryPath, allFile[currentFile].getName());
			} else {
				// 如果是目录就采用递归处理
				Logger.debug(destDirectoryPath + "/" + allFile[currentFile].getName().toString());
				copyDirectory(allFile[currentFile].getPath().toString(), destDirectoryPath + "/" + allFile[currentFile].getName().toString()); 
			}
		}
	}
	
	/**
	 * 连接失去的时候重新连接
	 * @throws IOException
	 */
	private void reConnect() throws IOException {
		while(!ftp.isConnected()) {
			connect();
		}
	}

	/**
	 * 拷贝文件
	 * @param src
	 * @param dest
	 * @throws IOException 
	 */
	private void copyFile(String src, String dirPath, String fileName) throws IOException{
		File file = new File(src);
		if(file.lastModified() > lastUpdate && file.length() != 0) {
			reConnect();
			InputStream is = new FileInputStream(file);
			ftp.setControlEncoding("GBK");
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftp.changeWorkingDirectory(dirPath);
			ftp.storeFile(fileName, is);
			is.close();
			Logger.debug("上传文件到" + "" + dirPath + "/" + fileName + "成功,这是第" + ++num + "个");
		}
	}
	
	/**
	 * 连接ftp服务器
	 * @throws IOException 
	 */
	private void connect() throws IOException {
		ftp = new FTPClient();
		ftp.connect(ipAdress);
		ftp.login(username, password);
	}
	
	/**
	 * 关闭连接
	 * @param ftp
	 * @throws IOException
	 */
	private void disConnect() throws IOException {
		ftp.disconnect();
	}
}

        可以发现,我没有做断点续传的功能,这也是程序中的一个缺陷,我会尽快完善,谢谢,发现代码有可改进之处,欢迎指出。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2012-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档