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断点续传,首先需要了解libcurl的基本用法。在提供的压缩包中,可能包含libcurl的动态链接库(dll)、静态库(lib)、头文件(.h)以及示例代码(cpp)。这些文件是构建使用libcurl的C/C++程序...
### FTP断点续传编程原理详解 #### 一、引言 FTP(File Transfer Protocol)是一种用于在网络上进行文件传输的标准协议。随着网络技术的发展,FTP的功能也在不断拓展和完善。其中,“断点续传”功能是用户非常关心...
标题"XuChuanFTP_Java_FTP断点续传"可能是指一个Java实现的FTP客户端库或者一个示例项目,专注于支持FTP的断点续传功能。这个项目可能是为了帮助开发者更方便地处理大文件的上传任务,尤其是在网络不稳定的情况下。 ...
ftp 断点续传实现 FTP 是一个非常常用的文件传输协议,它可以帮助用户上传和下载文件到远程服务器中。断点续传是 FTP 协议的一个重要特性,它可以在文件传输过程中断后继续传输,避免了文件传输的中断和失败。在这...
FTP断点续传是网络上传下载技术中的一个重要概念,它允许用户在中断连接后从上次停止的地方继续传输文件,极大地提高了文件传输的效率和可靠性。本压缩包“Ftp断点续传源码.rar”提供了使用Delphi编程语言实现FTP...
在基于MFC的FTP断点续传客户端中,主要涉及到以下几个关键知识点: 1. MFC库:MFC是微软为Windows平台提供的一套C++类库,它封装了Windows API,提供了面向对象的编程接口,使得开发者能更高效地创建Windows应用...
本文将深入探讨如何使用Java实现FTP断点续传,并提供相关的源码整理。 FTP断点续传的核心原理是通过FTP协议中的REST(Restart)命令来实现。REST命令告诉服务器从指定的位置开始继续传输数据,而不是重新开始。在...
在C语言中实现FTP断点续传涉及到以下几个关键知识点: 1. **FTP协议基础**:首先,你需要理解FTP协议的基本工作原理,包括连接、登录、命令交互、数据传输等过程。FTP使用TCP作为传输层协议,通过控制连接和数据...
综上所述,这个C语言实现的FTP断点续传项目涵盖了网络编程、文件操作、错误处理等多个方面,对于深入理解FTP协议和C语言的网络编程有极大的帮助。开发者通过这个项目,不仅可以学习到如何编写FTP客户端,还能了解到...
FTP断点续传的一些命令
实现FTP断点续传的关键在于保存和识别已传输的数据位置。这通常通过记录文件的当前位置(偏移量)和已传输的字节数来完成。当上传暂停后,客户端可以记住这个位置,再次连接时,只需从上次断开的地方开始继续传输。 ...
以下是一些关于如何在VS2008中实现FTP断点续传的关键知识点: 1. **FTP基础知识**:理解FTP的工作原理,包括命令结构、数据连接类型(主动和被动模式)以及FTP的控制和数据通道。 2. **FtpWebRequest类**:这是...
"c#FTP断点续传客户端"是指使用C#编程语言开发的FTP客户端软件,它特别强调了支持断点续传功能,这意味着在文件传输过程中如果因网络问题中断,可以在恢复连接后从上次断开的位置继续传输,提高了文件传输的可靠性和...
在Android平台上实现FTP断点续传下载功能,可以极大地提高用户下载大文件的效率和体验。断点续传允许应用程序在文件下载中断后从上次停止的地方继续,而不是重新开始整个下载过程。以下是对这一主题的详细阐述: 1....
用apache的FTP实现断点续传 - janestone的专栏 - 博客频道 - CSDN.NET (2012年5月21日) java实现FTP多线程断点续传,上传下载! - java学习与交流 - j2ee学习网 - j2ee学习网 (2012年5月21日) 用 Java 实现断点续传 ...
标题提到的“C的FTP断点续传的客户端源代码”是用C语言实现的一个FTP客户端程序,它集成了断点续传功能,能够在VC(Visual C++)环境中编译和运行。VC是一个流行的Microsoft开发环境,支持C和C++编程,提供了丰富的...
标题中的“FTP_Client_xulp.rar_c 断点续传_ftp client_ftp断点_ftp断点续传_site:www.pu”表明这是一个关于FTP客户端的项目,特别强调了其支持断点续传功能,这在大文件传输时非常有用。这个项目可能是在C语言环境...
5. **NSInputStream 和 NSOutputStream**: 在实现FTP断点续传时,可能会用到`NSInputStream`和`NSOutputStream`来读取和写入文件流,控制文件的传输过程。 6. **文件管理**: iOS提供了`FileManager`类用于文件系统...