package cn.ksource.core.util;
|
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.io.FileOutputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.io.OutputStream;
|
import java.util.Properties;
|
|
import cn.ksource.web.Constants;
|
import org.apache.commons.net.ftp.FTP;
|
import org.apache.commons.net.ftp.FTPClient;
|
import org.apache.commons.net.ftp.FTPFile;
|
import org.apache.commons.net.ftp.FTPReply;
|
public class FtpClient {
|
|
public FTPClient ftpClient = new FTPClient();
|
|
/**
|
* java编程中用于连接到FTP服务器
|
*
|
* @param hostname
|
* 主机名
|
* @param port
|
* 端口
|
* @param username
|
* 用户名
|
* @param password
|
* 密码
|
* @return 是否连接成功
|
* @throws IOException
|
*/
|
public boolean connect() throws IOException {
|
Properties props = new Properties();
|
InputStream in = FtpClient.class.getResourceAsStream("/"+ Constants.APP_CONF_FILE);
|
props.load(in);
|
in.close();
|
String url = props.getProperty("ftp.url");
|
String port = props.getProperty("ftp.port");
|
String username = props.getProperty("ftp.username");
|
String password = props.getProperty("ftp.pwd");
|
ftpClient.connect(url, Integer.valueOf(port));
|
ftpClient.setControlEncoding("GBK");
|
if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
|
if (ftpClient.login(username, password)) {
|
System.out.println("ftp登陆成功");
|
return true;
|
}
|
}
|
disconnect();
|
return false;
|
}
|
|
/**
|
* 从FTP服务器上下载文件
|
*
|
* @param remote
|
* 远程文件路径
|
* @param local
|
* 本地文件路径
|
* @return 是否成功
|
* @throws IOException
|
*/
|
public DownloadStatus download(String remote, String local) throws IOException {
|
ftpClient.enterLocalPassiveMode();
|
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
|
DownloadStatus result;
|
|
FTPFile[] files = ftpClient.listFiles(remote);
|
if (files.length != 1) {
|
System.out.println("远程文件不唯一");
|
return DownloadStatus.Remote_File_Noexist;
|
}
|
|
long lRemoteSize = files[0].getSize();
|
File f = new File(local);
|
if (f.exists()) {
|
long localSize = f.length();
|
if (localSize >= lRemoteSize) {
|
System.out.println("本地文件大小大于远程文件大小,下载中止");
|
return DownloadStatus.Local_Bigger_Remote;
|
}
|
|
FileOutputStream out = new FileOutputStream(f, true);
|
ftpClient.setRestartOffset(localSize);
|
InputStream in = ftpClient.retrieveFileStream(remote);
|
byte[] bytes = new byte[1024];
|
long step = lRemoteSize / 100;
|
long process = localSize / step;
|
int c;
|
while ((c = in.read(bytes)) != -1) {
|
out.write(bytes, 0, c);
|
localSize += c;
|
long nowProcess = localSize / step;
|
if (nowProcess > process) {
|
process = nowProcess;
|
if (process % 10 == 0)
|
System.out.println(process);
|
}
|
}
|
in.close();
|
out.close();
|
boolean isDo = ftpClient.completePendingCommand();
|
if (isDo) {
|
result = DownloadStatus.Download_From_Break_Success;
|
} else {
|
result = DownloadStatus.Download_From_Break_Failed;
|
}
|
} else {
|
OutputStream out = new FileOutputStream(f);
|
InputStream in = ftpClient.retrieveFileStream(remote);
|
byte[] bytes = new byte[1024];
|
long step = lRemoteSize / 100;
|
long process = 0;
|
long localSize = 0L;
|
int c;
|
while ((c = in.read(bytes)) != -1) {
|
out.write(bytes, 0, c);
|
localSize += c;
|
long nowProcess = localSize / step;
|
if (nowProcess > process) {
|
process = nowProcess;
|
if (process % 10 == 0)
|
System.out.println(process);
|
}
|
}
|
in.close();
|
out.close();
|
boolean upNewStatus = ftpClient.completePendingCommand();
|
if (upNewStatus) {
|
result = DownloadStatus.Download_New_Success;
|
} else {
|
result = DownloadStatus.Download_New_Failed;
|
}
|
}
|
return result;
|
}
|
|
|
/**
|
* 从FTP服务器上下载文件
|
*
|
* @param remote
|
* 远程文件路径
|
* @param local
|
* 本地文件路径
|
* @return 是否成功
|
* @throws IOException
|
*/
|
public InputStream download(String remote) throws IOException {
|
ftpClient.enterLocalPassiveMode();
|
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
|
//ftpClient.setRestartOffset(1000);
|
String remoteFileNameFormat = new String(remote.getBytes("GBK"),"iso-8859-1");
|
InputStream in = ftpClient.retrieveFileStream(remoteFileNameFormat);
|
//ftpClient.completePendingCommand();
|
return in;
|
}
|
|
public boolean exist(String remote) {
|
try {
|
FTPFile[] files = ftpClient.listFiles(remote);
|
if (files.length == 1) {
|
return true;
|
}
|
return false;
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return false;
|
}
|
|
/**
|
* ftp文件删除
|
*
|
* @param remote
|
* @return
|
* @version V1.0.0
|
* @author
|
* @date Oct 29, 2013 1:13:59 PM
|
*/
|
public boolean deleteFile(String remote) {
|
try {
|
if (exist(remote)) {
|
return this.ftpClient.deleteFile(remote);
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return false;
|
}
|
|
/**
|
* 上传文件到FTP服务器,支持断点续传
|
*
|
* @param local
|
* 本地文件名称,绝对路径
|
* @param remote
|
* 远程文件路径,使用/home/directory1/subdirectory/file.ext
|
* 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构
|
* @return 上传结果
|
* @throws IOException
|
*/
|
public UploadStatus upload(String local, String remote) throws IOException {
|
// 设置PassiveMode传输
|
ftpClient.enterLocalPassiveMode();
|
// 设置以二进制流的方式传输
|
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
|
UploadStatus result;
|
// 对远程目录的处理
|
String remoteFileName = remote;
|
if (remote.contains("/")) {
|
remoteFileName = remote.substring(remote.lastIndexOf("/") + 1);
|
String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
|
if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(directory)) {
|
// 如果远程目录不存在,则递归创建远程服务器目录
|
int start = 0;
|
int end = 0;
|
if (directory.startsWith("/")) {
|
start = 1;
|
} else {
|
start = 0;
|
}
|
end = directory.indexOf("/", start);
|
while (true) {
|
String subDirectory = remote.substring(start, end);
|
if (!ftpClient.changeWorkingDirectory(subDirectory)) {
|
if (ftpClient.makeDirectory(subDirectory)) {
|
ftpClient.changeWorkingDirectory(subDirectory);
|
} else {
|
System.out.println("创建目录失败");
|
return UploadStatus.Create_Directory_Fail;
|
}
|
}
|
|
start = end + 1;
|
end = directory.indexOf("/", start);
|
|
// 检查所有目录是否创建完毕
|
if (end <= start) {
|
break;
|
}
|
}
|
}
|
}
|
|
String remoteFileNameFormat = new String(remoteFileName.getBytes("GBK"),"iso-8859-1");
|
// 检查远程是否存在文件
|
FTPFile[] files = ftpClient.listFiles(remoteFileName);
|
if (files.length == 1) {
|
long remoteSize = files[0].getSize();
|
File f = new File(local);
|
long localSize = f.length();
|
if (remoteSize == localSize) {
|
return UploadStatus.File_Exits;
|
} else if (remoteSize > localSize) {
|
return UploadStatus.Remote_Bigger_Local;
|
}
|
|
// 尝试移动文件内读取指针,实现断点续传
|
InputStream is = new FileInputStream(f);
|
if (is.skip(remoteSize) == remoteSize) {
|
ftpClient.setRestartOffset(remoteSize);
|
if (ftpClient.storeFile(remoteFileNameFormat, is)) {
|
is.close();
|
return UploadStatus.Upload_From_Break_Success;
|
}
|
}
|
|
// 如果断点续传没有成功,则删除服务器上文件,重新上传
|
if (!ftpClient.deleteFile(remoteFileName)) {
|
return UploadStatus.Delete_Remote_Faild;
|
}
|
is = new FileInputStream(f);
|
if (ftpClient.storeFile(remoteFileNameFormat, is)) {
|
result = UploadStatus.Upload_New_File_Success;
|
} else {
|
result = UploadStatus.Upload_New_File_Failed;
|
}
|
is.close();
|
} else {
|
InputStream is = new FileInputStream(local);
|
if (ftpClient.storeFile(remoteFileNameFormat, is)) {
|
result = UploadStatus.Upload_New_File_Success;
|
} else {
|
result = UploadStatus.Upload_New_File_Failed;
|
}
|
is.close();
|
}
|
return result;
|
}
|
|
/**
|
* 上传文件到FTP服务器,支持断点续传
|
*
|
* @param local
|
* 本地文件名称,绝对路径
|
* @param remote
|
* 远程文件路径,使用/home/directory1/subdirectory/file.ext
|
* 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构
|
* @return 上传结果
|
* @throws IOException
|
*/
|
public UploadStatus upload(InputStream is, String remote) throws IOException {
|
// 设置PassiveMode传输
|
ftpClient.enterLocalPassiveMode();
|
// 设置以二进制流的方式传输
|
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
|
UploadStatus result;
|
// 对远程目录的处理
|
String remoteFileName = remote;
|
if (remote.contains("/")) {
|
remoteFileName = remote.substring(remote.lastIndexOf("/") + 1);
|
String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
|
if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(directory)) {
|
// 如果远程目录不存在,则递归创建远程服务器目录
|
int start = 0;
|
int end = 0;
|
if (directory.startsWith("/")) {
|
start = 1;
|
} else {
|
start = 0;
|
}
|
end = directory.indexOf("/", start);
|
while (true) {
|
String subDirectory = remote.substring(start, end);
|
if (!ftpClient.changeWorkingDirectory(subDirectory)) {
|
if (ftpClient.makeDirectory(subDirectory)) {
|
ftpClient.changeWorkingDirectory(subDirectory);
|
} else {
|
System.out.println("创建目录失败");
|
return UploadStatus.Create_Directory_Fail;
|
}
|
}
|
|
start = end + 1;
|
end = directory.indexOf("/", start);
|
|
// 检查所有目录是否创建完毕
|
if (end <= start) {
|
break;
|
}
|
}
|
}
|
}
|
|
String remoteFileNameFormat = new String(remoteFileName.getBytes("GBK"),"iso-8859-1");
|
// 检查远程是否存在文件
|
FTPFile[] files = ftpClient.listFiles(remoteFileName);
|
if (files.length == 1) {
|
if (ftpClient.storeFile(remoteFileNameFormat,is)) {
|
result = UploadStatus.Upload_New_File_Success;
|
} else {
|
result = UploadStatus.Upload_New_File_Failed;
|
}
|
is.close();
|
} else {
|
if (ftpClient.storeFile(remoteFileNameFormat,is)) {
|
result = UploadStatus.Upload_New_File_Success;
|
} else {
|
result = UploadStatus.Upload_New_File_Failed;
|
}
|
is.close();
|
}
|
return result;
|
}
|
|
/**
|
* 断开与远程服务器的连接
|
*
|
* @throws IOException
|
*/
|
public void disconnect() throws IOException {
|
if (ftpClient.isConnected()) {
|
ftpClient.disconnect();
|
}
|
}
|
|
/**
|
* 创建文件夹
|
*
|
* @param remote
|
* @param ftpClient
|
* @return
|
* @throws IOException
|
*/
|
public UploadStatus CreateDirecroty(String remote) throws IOException {
|
UploadStatus status = UploadStatus.Create_Directory_Success;
|
String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
|
if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(directory)) {
|
int start = 0;
|
int end = 0;
|
if (directory.startsWith("/")) {
|
start = 1;
|
} else {
|
start = 0;
|
}
|
end = directory.indexOf("/", start);
|
while (true) {
|
String subDirectory = remote.substring(start, end);
|
if (!ftpClient.changeWorkingDirectory(subDirectory)) {
|
if (ftpClient.makeDirectory(subDirectory)) {
|
ftpClient.changeWorkingDirectory(subDirectory);
|
} else {
|
System.out.println("创建文件夹失败");
|
return UploadStatus.Create_Directory_Fail;
|
}
|
}
|
start = end + 1;
|
end = directory.indexOf("/", start);
|
if (end <= start) {
|
break;
|
}
|
}
|
}
|
return status;
|
}
|
|
}
|