首先得新建一个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();
// }
}
}