FTP文件上传与下载

首先得新建一个FTP服务器,设定其访问的用户名和密码,并将其配置在配置文件当中:

配置文件ftpFile.properties

##fileupload
username=z2ZCJNw1qZk=
password=hCgxzEfVwm4=
ipAddress=192.168.1.103
port=21

配置文件经过加密的处理,BASE64加密解密:

package com.xuzengqiang.design.core.utils;

import java.security.MessageDigest;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * 数据加密与解密
 * BASE64
 * 
 * @author xuzengqiang
 * @since 2014-09-25
 */
@SuppressWarnings("all")
public class DataEncrypt {

	// BASE64解密
	public static byte[] decryptBASE64(String key) throws Exception {
		return (new BASE64Decoder()).decodeBuffer(key);
	}

	// BASE64加密
	public static String encryptBASE64(byte[] key) throws Exception {
		return (new BASE64Encoder()).encodeBuffer(key);
	}

}
DES加密与解密:DESCode.java

package com.xuzengqiang.design.core.utils;

import java.net.URLDecoder;
import java.security.Key;
import java.security.SecureRandom;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

/**
 * DESC对称加密解密 美国数据加密标准,密钥长度为56位,明文按64位进行分组,将分组后的明文组和56位的密钥按位替 代或交换的方法形成密文组的加密方法。
 * 特点:分组时间短,密钥短,密码生命周期短,运行速度慢
 * 原理:入口参数有key,data,mode,key:加密解密的密钥,data:加密解密的数据,mode工作模式
 * 当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密时, key用于对数据解密
 * 
 * @author xuzengqiang
 * @since 2014-09-25
 */
@SuppressWarnings("all")
public class DESCoder extends DataEncrypt {
	// 采用的算法
	public static final String ALGORITHM = "DES";

	// 生成密钥,data是一个已经用base64加密的数据
	public static String initKey(String data) throws Exception {
		// DESC算法要求有一个可信任的随机数源
		SecureRandom random = null;
		if (StringUtils.isEmpty(data)) {
			random = new SecureRandom();
		} else {
			random = new SecureRandom(decryptBASE64(data));
		}
		// 用于生产密钥,即秘密密钥生成器
		KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
		generator.init(random);
		// 生成一个密钥
		SecretKey secret = generator.generateKey();
		// BASE64加密
		return encryptBASE64(secret.getEncoded());
	}

	/**
	 * 加密
	 * @param password:需要加密的密码
	 * @param data:加密后的密钥字符串
	 * Cipher:提供了加密和解密的功能,调用getInstance("转换名称")创建对象
	 * 转换名称为加密算法的名称,如:DES
	 * mode:工作模式
	 * Cipher.ENCRYPT_CODE:用于将Cipher初始化为加密模式的常量
	 * DECRYPT_CODE:将Cipher初始化为解密模式的常量
	 * WRAP_MODE:初始化为密钥包装模式的常量
	 * UNWRAP_MODE:用于将 Cipher 初始化为密钥解包模式的常量
	 * PUBLIC_KEY:用于表示要解包的密钥为"公钥"的常量
	 * PRIVATE_KEY:用于表示要解包的密钥为“私钥”的常量
	 * SECRET_KEY:用于表示要解包的密钥为“秘密密钥”的常量。
	 * 方法:
	 * getProvider():返回此 Cipher对象的提供者。
	 * getAlgorithm():返回此 Cipher对象的算法名称。
	 * init(int mode,Key key):用密钥初始化Cipher,mode:为工作模式,key为密钥
	 * doFinal():返回一个对应工作模式下结果下的缓冲区
	 */
	public static byte[] encrypt(String password, String data) throws Exception {
		Key key = toKey(decryptBASE64(data));
		//返回指定对象的Cipher对象
		Cipher cipher = Cipher.getInstance(ALGORITHM);
		cipher.init(Cipher.ENCRYPT_MODE, key);
		byte[] buffer = cipher.doFinal(password.getBytes("UTF-8"));
		return buffer;
	}

	// 解密
	public static String decrypt(byte[] password, String data) throws Exception {
		Key key = toKey(decryptBASE64(data));
		Cipher cipher = Cipher.getInstance(ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, key);
		byte[] buffer = cipher.doFinal(password);
		return new String(buffer);
	}

	// 密钥转化:byte[]转Key
	public static Key toKey(byte[] keyByte) throws Exception {
		KeySpec spec = new DESKeySpec(keyByte);
		SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
		return factory.generateSecret(spec);
	}
	
	/**
	 * 对于已经加密的密码获取解密后的数值
	 * @param password:加密后的密码
	 * @param keyString:加密后的密钥字符串
	 * @return 解密后的密码
	 */
	public static String getValue(String password,String keyString) throws Exception {
		return DESCoder.decrypt(decryptBASE64(password), keyString);
	}
	
	public static void main(String[] args) {
		try {
			String password = "heyf";
			String keyData = initKey("strong");
			System.out.println("密钥为:"+keyData);
			byte[] data = encrypt(password, keyData);
			System.err.println("加密后:"+encryptBASE64(data));
			System.err.println("解密后:"+decrypt(data, keyData));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
配置文件的读取:ConfigurationUtils.java

package com.xuzengqiang.design.core.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 配置文件的读取
 * 
 * @author xuzengqiang
 * @since 2014-09-25
 */
@SuppressWarnings("all")
public class ConfigurationUtils {

	/**
	 * 对指定配置文件的数据进行读取 config:配置文件名
	 * 
	 * @return
	 */
	public static Properties getProperties(String config) {
		Properties env = new Properties();
		InputStream is = ConfigurationUtils.class.getClassLoader().getResourceAsStream(config);
		try {
			env.load(is);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			Resource.destoryResource(is);
		}
		return env;
	}

	// properties转map
	public static Map<String, String> propertiesToMap(Properties properties) {
		Map<String, String> result = new HashMap<String, String>();
		// 取出properties中的所有key
		Enumeration enu = properties.propertyNames();
		while (enu.hasMoreElements()) {
			String actionName = String.valueOf(enu.nextElement());
			String methodName = properties.getProperty(String.valueOf(actionName));
			result.put(actionName, methodName);
		}
		return result;
	}
}
资源处理类,主要用于关闭资源等。

package com.xuzengqiang.design.core.utils;

import java.io.FileOutputStream;
import java.io.InputStream;

/**
 * 资源处理类
 * 
 * @author xuzengqiang
 * @since 2014-09-26
 */
public class Resource {

	// 释放资源InputStream
	public static void destoryResource(InputStream input) {
		try {
			if (input != null) {
				input.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 释放资源OutputStream
	public static void destoryResource(FileOutputStream fos) {
		try {
			if (fos != null) {
				fos.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
FTP客户端初始化

package com.xuzengqiang.design.common.upload.ftp;

import java.io.IOException;
import java.net.SocketException;
import java.util.Properties;

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

import com.xuzengqiang.design.core.utils.ConfigurationUtils;
import com.xuzengqiang.design.core.utils.DESCoder;

/**
 * FTP客户端
 * 
 * @author xuzengqiang
 * @Since 2014-09-25
 */
@SuppressWarnings("all")
public class FtpClientInstance {

	// 配置文件路径
	private static final String FTP_CONFIG = "ftpFile.properties";
	// 密文
	private static final String DATA = "strong";

	// 用户名
	private static String USERNAME = null;

	// 密码
	private static String PASSWORD = null;

	// ip地址
	private static String HOST = null;

	// 端口号.默认为21
	private static Integer PORT = null;

	// FTP客户端
	private static FTPClient ftpClient;

	static {
		Properties properties = ConfigurationUtils.getProperties(FTP_CONFIG);
		USERNAME = properties.getProperty("username");
		PASSWORD = properties.getProperty("password");
		HOST = properties.getProperty("ipAddress");
		PORT = Integer.valueOf(properties.getProperty("port"));
		// 用户名和密码需要进行解密处理
		try {
			String keyString = DESCoder.initKey(DATA);
			USERNAME = DESCoder.getValue(USERNAME, keyString);
			PASSWORD = DESCoder.getValue(PASSWORD, keyString);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static FTPClient getInstance() {
		if (ftpClient == null) {
			int reply;
			try {
				ftpClient = new FTPClient();
				// ftpClient.configure(getFTPConfig());
				ftpClient.setControlEncoding("UTF-8");
				// 连接FTP服务器
				ftpClient.connect(HOST, PORT);
				// 服务器连接回答
				reply = ftpClient.getReplyCode();
				if (FTPReply.isPositiveCompletion(reply)) {
					boolean loginStatus = ftpClient.login(USERNAME, PASSWORD);
					if (loginStatus) {
						System.out.println("服务器连接成功...");
					}
				} else {
					ftpClient.disconnect();
				}

			} catch (SocketException e) {
				e.printStackTrace();
				System.err.print("登录FTP" + HOST + "服务器失败,连接超时!");
			} catch (IOException e) {
				e.printStackTrace();
				System.err.print("登录FTP" + HOST + "服务器失败,FTP服务器无法打开!");
			}
		}
		return ftpClient;
	}

	// 客户端配置
	public static FTPClientConfig getFTPConfig() {
		FTPClientConfig ftpConfig = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
		ftpConfig.setServerLanguageCode("zh");
		return ftpConfig;
	}

	// 关闭连接
	public static void closeConnect(FTPClient client) {
		try {
			if (client != null) {
				client.logout();
				client.disconnect();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		FtpClientInstance.getInstance();
	}

}
FTP工具类:

package com.xuzengqiang.design.common.upload.ftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

import com.xuzengqiang.design.core.utils.Resource;

/**
 * FTP文件操作
 * 
 * @author xuzengqiang
 * @since 2014-09-26
 */
@SuppressWarnings("all")
public class FTPUtils {

	/**
	 * 描述:上传单个文件
	 * 
	 * @param File
	 *            :文件
	 * @param remoteFilePath
	 *            :服务器文件路径
	 * @param fileName
	 *            :文件名
	 */
	public static boolean upload(File file, String remoteFilePath, String fileName) {
		Boolean flag = Boolean.TRUE;
		InputStream in = null;
		FTPClient client = FtpClientInstance.getInstance();
		try {
			in = new FileInputStream(file);
			// 设置文件类型和格式传送
			client.setFileType(FTP.BINARY_FILE_TYPE);
			client.enterLocalPassiveMode();
			// 切换路径到服务器端路径,为空跳转到根目录
			if (remoteFilePath == null) {
				client.changeWorkingDirectory("/");
			} else {
				client.changeWorkingDirectory(remoteFilePath);
			}
			// 给定一个文件名并采取从给定的InputStream输入服务器的文件,该方法不会关闭InputStream
			flag = client.storeUniqueFile(fileName, in);
			if (flag) {
				System.out.println("文件上传成功!");
			}
		} catch (FileNotFoundException e) {
			System.err.println("文件未找到...");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			Resource.destoryResource(in); // 释放资源
		}
		return flag;
	}

	/**
	 * 到指定服务器端路径上下载单个文件
	 * 
	 * @param fileName
	 *            :文件名
	 * @param remoteFilePath
	 *            :服务器端路径,为null是表示根目录
	 * @param fileName
	 *            :下载到本地的路径
	 * @return
	 */
	public static boolean downLoad(String fileName, String remoteFilePath, String filePath) {
		Boolean flag = Boolean.TRUE;
		FileOutputStream fos = null;
		FTPClient client = FtpClientInstance.getInstance();
		try {
			File file = new File(filePath);
			if (!file.exists()) {
				file.mkdirs();
			}
			// 设置文件类型和格式传送
			client.setFileType(FTP.BINARY_FILE_TYPE);
			client.enterLocalPassiveMode();
			// 获取指定目录下的所有文件列表(包括文件夹)
			FTPFile[] ftpFiles = client.listFiles(remoteFilePath);
			boolean find = false;
			for (FTPFile ftpFile : ftpFiles) {
				if (ftpFile.getName().equals(fileName)) { // 是否找到该文件
					String result = filePath + File.separator + fileName;
					fos = new FileOutputStream(new File(result));
					flag = client.retrieveFile(fileName, fos);
					if (flag) {
						System.out.println("文件下载成功!");
					}
					find = true;
					break;
				}
			}
			if (find == false) {
				System.err.println("未找到指定文件!");
			}
		} catch (FileNotFoundException e) {
			System.err.println("文件未找到...");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			Resource.destoryResource(fos); // 释放资源
		}
		return flag;
	}

	/**
	 * 递归下载整个文件夹
	 * 
	 * @param remoteDirectory
	 *            :服务器路径,null时表示根目录
	 * @param filePath
	 *            :下载到本地的路径
	 * @return
	 */
	public static boolean loadFloder(String remoteDirectory, String filePath) {
		Boolean flag = Boolean.FALSE;
		FileOutputStream fos = null;
		FTPClient client = FtpClientInstance.getInstance();
		try {
			if (remoteDirectory == null) {
				remoteDirectory = "";
			}
			File file = new File(filePath);
			if (!file.exists()) {
				file.mkdirs();
			}
			// 设置文件类型和格式传送
			client.setFileType(FTP.BINARY_FILE_TYPE);
			// 在每次数据连接之前,通知FTP Server开通一个端口来传输数据
			client.enterLocalPassiveMode();

			// 获取所有的文件夹
			// FTPFile[] ftpFiles = client.listDirectories(remoteFilePath);

			FTPFile[] ftpFiles = client.listFiles(remoteDirectory);
			for (FTPFile ftpFile : ftpFiles) {
				if (ignoreRoot(ftpFile.getName())) // 过滤掉.和..两个目录
					continue;
				System.out.println(ftpFile.getName());
				if (ftpFile.isDirectory()) { // 如果是个目录则继续递归
					String newFilePath = filePath + File.separator + ftpFile.getName();
					String newRemoteDirectory = remoteDirectory + File.separator + ftpFile.getName();
					// 递归
					loadFloder(newRemoteDirectory, newFilePath);
				} else {
					String fileName = ftpFile.getName();
					String result = filePath + File.separator + fileName;
					fos = new FileOutputStream(new File(result));
					flag = client.retrieveFile(fileName, fos);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 创建一个远程目录
	 * 
	 * @param remoteDirectory
	 *            :路径名称:类似/xuzengqiang/image/case,会一级一级创建,
	 *            如果xuzengqiang不存在,则创建,反之继续
	 * @return 创建目录是否成功
	 * @throws Exception
	 */
	public static boolean createDirectory(String remoteDirectory) throws Exception {
		Boolean flag = Boolean.FALSE;
		FTPClient client = FtpClientInstance.getInstance();
		if (remoteDirectory == null) {
			client.changeWorkingDirectory("/"); // 切换到根目录
		} else {
			if (client.printWorkingDirectory().equals(remoteDirectory)) {
				return true;
			}
			remoteDirectory = new String(remoteDirectory.getBytes("GBK"), "UTF-8");
			if (remoteDirectory.startsWith("/")) {
				remoteDirectory = "/" + remoteDirectory;
			}
			// 如果不等于根目录获取不能进入该目录,说明目录不存在则创建目录
			if (!remoteDirectory.equalsIgnoreCase("/") && !client.changeWorkingDirectory(remoteDirectory)) {
				// 记录位置,start:起始位置,end为结束位置截取子目录名称
				int start = remoteDirectory.indexOf("/");
				int end = 0;
				if (!remoteDirectory.endsWith("/")) {
					remoteDirectory = remoteDirectory + "/";
				}
				while ((end = remoteDirectory.indexOf("/", start + 1)) != -1) {
					String subPath = remoteDirectory.substring(start, end);
					// 如果子目录不存在,则创建
					if (!client.changeWorkingDirectory(subPath)) {
						if (client.makeDirectory(subPath)) {
							client.changeWorkingDirectory(subPath);
						}
					}
					start = end + 1;
				}
			}
		}
		return flag;
	}

	/**
	 * 获取指定文件目录下的所有文件名和文件夹名(单层目录), 当remoteDirectory=null时访问根目录下所有文件
	 * fileFlag:false查询出所有文件夹名称,true:查询出所有的文件名称
	 * 
	 * @param directory
	 *            :目录
	 * @return
	 */
	public static List<String> getFileList(String remoteDirectory, Boolean fileFlag) {
		List<String> fileList = new ArrayList<String>();
		FTPClient client = FtpClientInstance.getInstance();
		try {
			if (!remoteDirectory.startsWith("/")) {
				remoteDirectory = "/" + remoteDirectory;
			}
			client.changeWorkingDirectory(remoteDirectory);
			// 获取指定目录下的所有文件名,返回一个string[]
			if (fileFlag) {
				fileList = Arrays.asList(client.listNames(remoteDirectory));
			} else {
				// 可能会出现两个根目录./和../
				FTPFile[] ftpFiles = client.listDirectories(remoteDirectory);
				for (FTPFile ftpFile : ftpFiles) {
					if (ftpFile.isDirectory() && !ignoreRoot(ftpFile.getName())) {
						fileList.add(ftpFile.getName());
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return fileList;
	}

	/**
	 * 获取指定目录下的所有文件和文件夹名称
	 * 
	 * @param remoteDirectory
	 *            :服务器目录,为""或者null时表示根目录
	 * @return
	 */
	public static List<String> getAllFiles(String remoteDirectory) {
		List<String> fileList = new ArrayList<String>();
		FTPClient client = FtpClientInstance.getInstance();
		try {
			client.changeWorkingDirectory(remoteDirectory);
			FTPFile[] ftpFiles = client.listFiles(remoteDirectory);
			for (FTPFile ftpFile : ftpFiles) {
				if (!ignoreRoot(ftpFile.getName())) {
					fileList.add(ftpFile.getName());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return fileList;
	}

	// 忽略根目录:./和../
	public static boolean ignoreRoot(String path) {
		return ".".equals(path) || "..".equals(path);
	}

	/**
	 * 重命名
	 * 
	 * @param oldName
	 *            :旧文件名
	 * @param newName
	 *            :新文件名
	 */
	public static void renameFile(String oldName, String newName) {
		FTPClient client = FtpClientInstance.getInstance();
		try {
			// 重命名
			client.rename(oldName, newName);
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("重命名失败!");
		}
	}

	/**
	 * 删除单个文件
	 * 
	 * @param remoteDirectory
	 *            : 指定的服务器目录
	 * @param remoteFileName
	 *            :文件名称
	 */
	public static boolean deleteFile(String remoteDirectory, String remoteFileName) {
		FTPClient client = FtpClientInstance.getInstance();
		Boolean flag = Boolean.TRUE;
		try {
			if (!remoteDirectory.startsWith("/")) {
				remoteDirectory = "/" + remoteDirectory;
			}
			client.changeWorkingDirectory(remoteDirectory);
			flag = client.deleteFile(remoteFileName);
			if (flag) {
				System.out.println("文件删除成功!");
			} else {
				System.err.println("文件删除失败!可能是文件不存在或路径错误!");
			}
		} catch (IOException e) {
			e.printStackTrace();
			System.err.println("文件删除失败!");
		}
		return flag;
	}

	/**
	 * 删除指定文件夹下的所有文件和文件夹 文件路径必须以"/"开头 ,如果不是,则加上"/"
	 * 
	 * @param remoteDirectory
	 *            :服务器文件路径
	 */
	public static boolean deleteFloder(String remoteDirectory) {
		Boolean flag = Boolean.TRUE;
		FTPClient client = FtpClientInstance.getInstance();
		try {
			if (!remoteDirectory.startsWith("/")) {
				remoteDirectory = "/" + remoteDirectory;
			}
			client.changeWorkingDirectory(remoteDirectory);
			FTPFile[] ftpFiles = client.listFiles(remoteDirectory);
			for (FTPFile ftpFile : ftpFiles) {
				if (ignoreRoot(ftpFile.getName())) // 如果是根目录,直接跳出
					continue;
				if (ftpFile.isDirectory()) {
					deleteFloder(remoteDirectory + File.separator + ftpFile.getName());
				} else if (ftpFile.isFile()) {
					deleteFile(remoteDirectory, ftpFile.getName());
				}
			}
			// 跳转到父目录
			client.changeToParentDirectory();
			flag = client.removeDirectory(remoteDirectory);
			if (flag) {
				System.out.println("删除文件夹成功!");
			} else {
				System.err.println("删除文件夹失败!可能是权限不足或者路径错误或文件不存在!");
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("重命名失败!");
		}
		return flag;
	}

	public static void main(String[] args) {
		// FTPUtils.upload(new File("D:\\test.txt"), "/xuzengqiang/struts",
		// "test.zip");
		// List<String> list = getAllFiles("");
		// for (String s : list) {
		// System.out.println(s);
		// }
		// deleteFile("/xuzengqiang", "test.txt");
		// renameFile("test.txt", "测试23.txt");
		//
		// FTPUtils.downLoad("Struct2权威指南.pdf", null, "D:\\java");
		// FTPUtils.loadFloder(null, "D:\\abctest");
		// FTPUtils.deleteFloder("/xuzengqiang");
		// try {
		// FTPUtils.createDirectory("/xuzengqiang/struts/interceptor");
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值