import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
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;
import org.apache.log4j.Logger;
public class FTPUtil {
private static FTPClient ftpClient = new FTPClient();
private static Logger logger = Logger.getLogger(FTPUtil.class);
private static String encode_charset = "UTF-8";
private final static int CACHE_SIZE = 8*1024*1024;
private final static String DIRECTORY_CREATE_FAILED = "目录创建失败";
private final static String DIRECTORY_CREATE_SUCCESS = "目录创建成功";
private final static String UPLOAD_NEW_SUCCESS = "上传文件成功";
private final static String UPLOAD_NEW_FAILED = "上传文件失败";
private final static String UPLOAD_RESUME_SUCCESS = "断点续传成功";
private final static String UPLOAD_RESUME_FAILED = "断点续传失败";
private final static String FILE_EXISTS = "文件已存在 ";
private final static String FILE_DOES_NOT_MATCH = "文件不匹配";
/**
*
* @param ftpClient FTPClient
* @param localFile 本地文件路径
* @return 上传文件路径 (ftp://ip/dir/.../file.ext)
*/
public static String upload(FTPClient ftpClient,String localFile) {
try {
File file = new File(localFile);
ftpClient.enterLocalPassiveMode();// 设置PassiveMode传输
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 设置以二进制流的方式传输
ftpClient.setControlEncoding(encode_charset);// 设置编码格式
String fileName = new String(file.getName().getBytes(encode_charset), encode_charset);//防止文件名乱码
String dateDir = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String remoteFileName = "/" + dateDir + "/" + fileName;
// 检测目标路径是否存在
if (createDirecroty(ftpClient, remoteFileName) == DIRECTORY_CREATE_FAILED) {
logger.error(DIRECTORY_CREATE_FAILED);
return null;
}
String result = null;
FTPFile[] ftpFiles = ftpClient.listFiles("/" + dateDir);
logger.debug("上传后返回的文件名"+remoteFileName);
if(ftpFiles != null && ftpFiles.length >0){
for (FTPFile ftpFile : ftpFiles) {
// 若存在相同文件名文件,则判断是否进行断点续传
if(ftpFile.getName().equals(fileName)){
long remoteSize = ftpFile.getSize();
long localSize = file.length();
if (remoteSize == localSize) {
logger.error(FILE_EXISTS);
return null;
} else if (remoteSize > localSize) {
logger.error(FILE_DOES_NOT_MATCH);
return null;
}
// 尝试移动文件内读取指针,实现断点续传
result = uploadFile(remoteFileName, file,
ftpClient, remoteSize);
logger.debug("上传结果:" + result);
if(result.equals(UPLOAD_NEW_SUCCESS) || result.equals(UPLOAD_RESUME_SUCCESS)){
logger.debug(UPLOAD_RESUME_SUCCESS);
return remoteFileName.substring(1);
} else {
logger.error("上传失败!!!");
return null;
}
}
}
// 重新上传
ftpClient.deleteFile(remoteFileName);
result = uploadFile(remoteFileName, file, ftpClient, 0);
logger.debug("上传结果:" + result);
if(result.equals(UPLOAD_NEW_SUCCESS) || result.equals(UPLOAD_RESUME_SUCCESS)){
logger.debug(UPLOAD_NEW_SUCCESS);
return remoteFileName.substring(1);
} else {
logger.error("上传失败!!!");
return null;
}
} else {
// 重新上传
ftpClient.deleteFile(remoteFileName);
result = uploadFile( remoteFileName, file, ftpClient, 0);
logger.debug("上传结果:" + result);
if(result.equals(UPLOAD_NEW_SUCCESS) || result.equals(UPLOAD_RESUME_SUCCESS)){
logger.debug(UPLOAD_NEW_SUCCESS);
return remoteFileName.substring(1);
} else {
logger.error("上传失败!!!");
return null;
}
}
} catch (FileNotFoundException e) {
logger.error("文件不存在:" + e);
return null;
} catch (UnsupportedEncodingException e) {
logger.error("编码格式不支持:" + e);
return null;
} catch (IOException e) {
logger.error("IO错误:" + e);
return null;
} finally {
closeConnections();// 关闭连接
}
}
/**
*
* @param remoteFile
* @param localFile
* @param ftpClient
* @param remoteSize
* @return
* @throws IOException
*/
@SuppressWarnings("unchecked")
public static String uploadFile(String remoteFile,
File localFile, FTPClient ftpClient, long remoteSize)
throws IOException {
String status;
// 显示进度的上传
long step = localFile.length() / 100;
long process = 0;//百分比
long localreadbytes = 0L;
RandomAccessFile raf = new RandomAccessFile(localFile, "r");
OutputStream out = ftpClient.appendFileStream(new String(remoteFile
.getBytes(encode_charset), encode_charset));
// 断点续传
if (remoteSize > 0) {
ftpClient.setRestartOffset(remoteSize);
process = remoteSize / step;
raf.seek(remoteSize);
localreadbytes = remoteSize;
}
byte[] bytes = new byte[CACHE_SIZE];
int c;
while ((c = raf.read(bytes)) != -1) {
out.write(bytes, 0, c);
localreadbytes += c;
if (localreadbytes / step != process) {
process = localreadbytes / step;
System.out.println("上传进度:" + process);
// TODO 汇报上传状态
} }
out.flush();
raf.close();
out.close();
boolean result = ftpClient.completePendingCommand();
if (remoteSize > 0) {
status = result ? UPLOAD_RESUME_SUCCESS
: UPLOAD_RESUME_FAILED;
} else {
status = result ? UPLOAD_NEW_SUCCESS : UPLOAD_NEW_FAILED;
}
return status;
}
/**
* 递归创建远程服务器目录
*
* @param remote
* @param ftpClient FTPClient
* @return status
* @throws IOException
*/
private static String createDirecroty(FTPClient ftpClient, String remote)
throws IOException {
String status = DIRECTORY_CREATE_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 = new String(remote.substring(start, end));
if (!ftpClient.changeWorkingDirectory(subDirectory)) {
if(!ftpClient.makeDirectory(subDirectory))
return DIRECTORY_CREATE_FAILED;
ftpClient.changeWorkingDirectory(subDirectory);
}
start = end + 1;
end = directory.indexOf("/", start);
// 检查所有目录是否创建完毕
if (end <= start) {
break;
}
}
}
return status;
}
/**
*
* @param ftpHost 主机
* @param ftpUserName 用户名
* @param ftpPassword 密码
* @param ftpPort 端口
* @return
*/
public static FTPClient getFTPClient(String ftpHost, String ftpUserName,
String ftpPassword, int ftpPort) {
try {
ftpClient.setControlEncoding(encode_charset);
ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
logger.debug("ftp参数:ftpHost=" + ftpHost + " ftpUserName="
+ ftpUserName + " ftpPassword=" + ftpPassword + " ftpPort="
+ ftpPort);
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
logger.info("未连接到FTP,用户名或密码错误。");
ftpClient.disconnect();
} else {
logger.info("FTP连接成功。");
}
} catch (SocketException e) {
logger.info("FTP的IP地址可能错误,请正确配置" + e);
} catch (IOException e) {
logger.info("FTP的端口错误,请正确配置" + e);
}
return ftpClient;
}
/**
* 关闭连接
*/
private static void closeConnections() {
try {
if (ftpClient.isConnected()) {
ftpClient.disconnect();
}
} catch (IOException e) {
logger.info("关闭连接失败" + e);
}
}
public static void main(String[] args) throws IOException {
String ip = "10.3.1.190";
String username = "root";
String password = "root";
Integer port = 21;
FTPClient ftpClient = FTPUtil
.getFTPClient(ip, username, password, port);
String status = FTPUtil.upload(ftpClient,
"D:/temp/电影天堂www.dygod.net.三十极夜.中英双字.1024分辨率.rmvb");
System.out.println(status);
}
}
分享到:
相关推荐
利用libcurl实现ftp断点续传,文件压缩包里面只有dll,lib,.h和cpp文件,不是工程。
ftp实现断点续传,ftp支持上传续传 ftp断点续传基于c语言的实现。
精炼的内容,看过基本可以完成FTP断点续传的编程。
java实现ftp断点续传
delphi Ftp断点续传源码.rar(源码)
FTP断点续传的一些命令
Java上传文件到FTP服务器,支持断点续传
C语言实现ftp断点续传.rar.rar
android实现ftp断点续传下载类,完成后自动通知调用程序
java实现ftp断点续传Java实用源码整理learns
用apache的FTP实现断点续传 - janestone的专栏 - 博客频道 - CSDN.NET (2012年5月21日) java实现FTP多线程断点续传,上传下载! - java学习与交流 - j2ee学习网 - j2ee学习网 (2012年5月21日) 用 Java 实现断点续传 ...
c#FTP断点续传客户端 对文件进行删除 上传下载 重命名
基于MFC实现的FTP可断点续传的客户端,实现了断点上传和断点下载的功能,可以运行,无论是学习还是拿到项目中使用都很有用。
c的ftp断点续传的客户端源代码 VC中利用FTP协议实现多线程断点续传(附源码)
java实现FTP多线程断点续传
FTP客户端实现要建立两个通道,一个控制命令通道,让FTP服务器知道客户端要干什么,一个数据传输通道。所谓的两个通道只不过是两个调用了connect函数的连接,只是控制命令通道专门用来传输一些字符串命令信息,而...
用c语言实现文件的上传和下载功能;使用ftp协议,实现断点续传功能。文件包中包含完整的源代码。能编译通过。
自己写的单任务FTP断点续传程序,新创建的任务会存到日志文件中(可存储多个任务的日志),异常中断重启时可以选择指定任务继续下载。程序比较简单,也可以说比较简陋,有些问题并未细致的考虑,比如磁盘空间不足等...
FTP上传(断点续传)更新进度条 公司项目第一个版本