`
天极网络
  • 浏览: 9885 次
  • 性别: Icon_minigender_1
  • 来自: 朔州
社区版块
存档分类
最新评论

FTP断点续传

阅读更多

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);
	}
}

0
0
分享到:
评论

相关推荐

    利用libcurl实现ftp断点续传

    要利用libcurl实现FTP断点续传,首先需要了解libcurl的基本用法。在提供的压缩包中,可能包含libcurl的动态链接库(dll)、静态库(lib)、头文件(.h)以及示例代码(cpp)。这些文件是构建使用libcurl的C/C++程序...

    FTP断点续传编程原理

    ### FTP断点续传编程原理详解 #### 一、引言 FTP(File Transfer Protocol)是一种用于在网络上进行文件传输的标准协议。随着网络技术的发展,FTP的功能也在不断拓展和完善。其中,“断点续传”功能是用户非常关心...

    xuchuanftp_java_FTP断点续传_

    标题"XuChuanFTP_Java_FTP断点续传"可能是指一个Java实现的FTP客户端库或者一个示例项目,专注于支持FTP的断点续传功能。这个项目可能是为了帮助开发者更方便地处理大文件的上传任务,尤其是在网络不稳定的情况下。 ...

    ftp 断点续传实现

    ftp 断点续传实现 FTP 是一个非常常用的文件传输协议,它可以帮助用户上传和下载文件到远程服务器中。断点续传是 FTP 协议的一个重要特性,它可以在文件传输过程中断后继续传输,避免了文件传输的中断和失败。在这...

    Ftp断点续传源码.rar

    FTP断点续传是网络上传下载技术中的一个重要概念,它允许用户在中断连接后从上次停止的地方继续传输文件,极大地提高了文件传输的效率和可靠性。本压缩包“Ftp断点续传源码.rar”提供了使用Delphi编程语言实现FTP...

    基于MFC实现的FTP断点续传客户端

    在基于MFC的FTP断点续传客户端中,主要涉及到以下几个关键知识点: 1. MFC库:MFC是微软为Windows平台提供的一套C++类库,它封装了Windows API,提供了面向对象的编程接口,使得开发者能更高效地创建Windows应用...

    java实现ftp断点续传Java实用源码整理learns

    本文将深入探讨如何使用Java实现FTP断点续传,并提供相关的源码整理。 FTP断点续传的核心原理是通过FTP协议中的REST(Restart)命令来实现。REST命令告诉服务器从指定的位置开始继续传输数据,而不是重新开始。在...

    C语言实现ftp断点续传.rar.rar

    在C语言中实现FTP断点续传涉及到以下几个关键知识点: 1. **FTP协议基础**:首先,你需要理解FTP协议的基本工作原理,包括连接、登录、命令交互、数据传输等过程。FTP使用TCP作为传输层协议,通过控制连接和数据...

    C语言实现ftp断点续传

    综上所述,这个C语言实现的FTP断点续传项目涵盖了网络编程、文件操作、错误处理等多个方面,对于深入理解FTP协议和C语言的网络编程有极大的帮助。开发者通过这个项目,不仅可以学习到如何编写FTP客户端,还能了解到...

    FTP断点续传的一些命令

    FTP断点续传的一些命令

    FTP上传(断点续传)更新进度条

    实现FTP断点续传的关键在于保存和识别已传输的数据位置。这通常通过记录文件的当前位置(偏移量)和已传输的字节数来完成。当上传暂停后,客户端可以记住这个位置,再次连接时,只需从上次断开的地方开始继续传输。 ...

    VS2008实现ftp断点续传的代码

    以下是一些关于如何在VS2008中实现FTP断点续传的关键知识点: 1. **FTP基础知识**:理解FTP的工作原理,包括命令结构、数据连接类型(主动和被动模式)以及FTP的控制和数据通道。 2. **FtpWebRequest类**:这是...

    c#FTP断点续传客户端

    "c#FTP断点续传客户端"是指使用C#编程语言开发的FTP客户端软件,它特别强调了支持断点续传功能,这意味着在文件传输过程中如果因网络问题中断,可以在恢复连接后从上次断开的位置继续传输,提高了文件传输的可靠性和...

    android实现ftp断点续传下载类,完成后自动通知调用程序

    在Android平台上实现FTP断点续传下载功能,可以极大地提高用户下载大文件的效率和体验。断点续传允许应用程序在文件下载中断后从上次停止的地方继续,而不是重新开始整个下载过程。以下是对这一主题的详细阐述: 1....

    自己收集的多个Java FTP断点续传的例子源码

    用apache的FTP实现断点续传 - janestone的专栏 - 博客频道 - CSDN.NET (2012年5月21日) java实现FTP多线程断点续传,上传下载! - java学习与交流 - j2ee学习网 - j2ee学习网 (2012年5月21日) 用 Java 实现断点续传 ...

    c的ftp断点续传的客户端源代码

    标题提到的“C的FTP断点续传的客户端源代码”是用C语言实现的一个FTP客户端程序,它集成了断点续传功能,能够在VC(Visual C++)环境中编译和运行。VC是一个流行的Microsoft开发环境,支持C和C++编程,提供了丰富的...

    FTP_Client_xulp.rar_c 断点续传_ftp client_ftp断点_ftp断点续传_site:www.pu

    标题中的“FTP_Client_xulp.rar_c 断点续传_ftp client_ftp断点_ftp断点续传_site:www.pu”表明这是一个关于FTP客户端的项目,特别强调了其支持断点续传功能,这在大文件传输时非常有用。这个项目可能是在C语言环境...

    IOS FTP 支持断点续传

    5. **NSInputStream 和 NSOutputStream**: 在实现FTP断点续传时,可能会用到`NSInputStream`和`NSOutputStream`来读取和写入文件流,控制文件的传输过程。 6. **文件管理**: iOS提供了`FileManager`类用于文件系统...

Global site tag (gtag.js) - Google Analytics