/**
* 将文件上传至ftp服务器
*/
public class FtpUtils {
private static Logger logger = Logger.getLogger(FtpUtils.class);
public static FTPClient ftpClient = new FTPClient();
/**
* 初始化ftp服务器,连接ftp服务器
*
* @param hostname ftp IP
* @param port ftp 端口
* @param username 用户名
* @param password 密码
*/
public void initFtpClient(String hostname, Integer port, String username, String password) {
try {
ftpClient.setControlEncoding("utf-8");
System.out.println("connecting...ftp服务器:" + hostname + "," + port);
//链接服务器
ftpClient.connect(hostname, port);
//登录服务器
ftpClient.login(username, password);
//判断是否成功登录服务器
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
logger.error("connect failed...ftp服务器");
} else {
logger.info("connect success...ftp服务器");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 递归创建远程服务器目录
*
* @param ftpPath 上传文件的存放路径
* @param ftpClient 本地源文件路径
* @return
* @throws Exception
*/
private static upLoadStatus CreateDirectory(String ftpPath, FTPClient ftpClient) throws Exception {
upLoadStatus status = upLoadStatus.Create_Directory_Success;
String directory = ftpPath.substring(0, ftpPath.lastIndexOf("/") + 1);
if (directory.equalsIgnoreCase("/") && ftpClient.changeWorkingDirectory(new String(directory.getBytes("UTF-8")))) {
int start = 0;
int end = 0;
if (directory.startsWith("/")) {
start = 1;
} else {
start = 0;
}
end = directory.indexOf("/", start);
while (true) {
String subDirectory = new String(ftpPath.substring(start, end).getBytes("UTF-8"), "UTF-8");
if (!ftpClient.changeWorkingDirectory(subDirectory)) {
if (ftpClient.makeDirectory(subDirectory)) {
ftpClient.changeWorkingDirectory(subDirectory);
} else {
logger.error("创建目录失败");
return upLoadStatus.Create_Directory_Fail;
}
}
start = end + 1;
end = directory.indexOf("/", start);
if (end <= start) {
break;
}
}
}
logger.info("创建目录成功");
return status;
}
/**
* 文件的上传
*
* @param ftpPath ftp文件上传的保存路径
* @param inputStream 本地文件路径
* @return
*/
public static upLoadStatus upload(String inputStream, String ftpPath) throws Exception {
try {
//设置passiveMode传输
ftpClient.enterLocalPassiveMode();
logger.info("开始上传文件");
//二进制方式保存文件
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setControlEncoding("UTF-8");
upLoadStatus result;
//对远程目录的处理
String ftpFileName = ftpPath;
if (ftpPath.contains("/")) {
ftpFileName = ftpPath.substring(ftpPath.lastIndexOf("/") + 1);
if (CreateDirectory(ftpPath, ftpClient) == upLoadStatus.Create_Directory_Fail) {
logger.error("创建目录失败");
return upLoadStatus.Create_Directory_Fail;
}
FTPFile[] files = ftpClient.listFiles(new String(ftpFileName.getBytes("UTF-8"), "UTF-8"));
if (files.length == 1) {
long remoteSize = files[0].getSize();
File f = new File(inputStream);
long localSize = f.length();
if (remoteSize == localSize) {
logger.info("文件已经存在");
return upLoadStatus.File_Exits;
} else if (remoteSize > localSize) {
logger.info("远程文件大小大于本地文件大小");
return upLoadStatus.Remote_Bigger_Local;
}
result = uploadFile(ftpFileName, f, ftpClient, remoteSize);
if (result == upLoadStatus.Upload_Form_Break_Failed) {
if (!ftpClient.deleteFile(ftpFileName)) {
logger.error("远程文件删除失败");
return upLoadStatus.Delete_Remote_Failed;
}
result = uploadFile(ftpFileName, f, ftpClient, 0);
}
} else {
result = uploadFile(ftpFileName, new File(inputStream), ftpClient, 0);
}
logger.info("文件上传成功");
return result;
}
} catch (Exception e) {
logger.error("上传文件失败");
e.printStackTrace();
}
return null;
}
/***
* 文件的断点上传
* @param ftpFile 远程文件存放目录
* @param localFile 本地文件存放目录
* @param ftpClient
* @param remoteSize 已经上传文件的字节大小
* @return
* @throws Exception
*/
public static upLoadStatus uploadFile(String ftpFile, File localFile, FTPClient ftpClient, long remoteSize) throws Exception {
upLoadStatus status;
long step = localFile.length() / 100;
long process = 0;
long localreadBytes = 0L;
RandomAccessFile randomAccessFile = new RandomAccessFile(localFile, "r");
OutputStream out = ftpClient.appendFileStream(new String(ftpFile.getBytes("UTF-8"), "UTF-8"));
try {
if (remoteSize > 0) {
ftpClient.setRestartOffset(remoteSize);
process = remoteSize / step;
randomAccessFile.seek(remoteSize);
localreadBytes = remoteSize;
}
} catch (ArithmeticException e) {
e.printStackTrace();
}
byte[] bytes = new byte[1024];
int c;
while ((c = randomAccessFile.read(bytes)) != -1) {
out.write(bytes, 0, c);
localreadBytes += c;
if (step != 0) {
if (localreadBytes / step != process) {
process = localreadBytes / step;
logger.info("上传进度" + process);
}
}
}
out.flush();
randomAccessFile.close();
out.close();
boolean result = ftpClient.completePendingCommand();
if (remoteSize > 0) {
status = result ? upLoadStatus.Upload_Form_Break_Success : upLoadStatus.Upload_Form_Break_Failed;
} else {
status = result ? upLoadStatus.Upload_NewFile_Success : upLoadStatus.Upload_NewFile_Failed;
}
return status;
}
}
注意:upLoadStatus是自己写的一个枚举类。这个工具类是在看了无数博文之后参考,应用到项目中并测试成功的类,记录下来,当做工具类使用。