package com.unicom.util;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.SocketException;
import java.util.Map;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
/**
* @author chc
* @version 创建时间:2014-7-17
* FTP上传工具类
*/
public class FtpClientUtil {
private static int max_retry = 999;//连接FTP不成功后,重试次数
private static long wait_time = 5000;//隔5秒后重新连接
private static final ThreadLocal<Integer> retryIndexThreadLocal = new ThreadLocal<Integer>();
public static boolean connect(FTPClient client, String hostname, int port, String username,
String password) throws SocketException, IOException {
client.setControlEncoding("UTF-8");
client.connect(hostname, port);
if (client.login(username, password)) {
// 设置PassiveMode传输
client.enterLocalPassiveMode();
// 设置以二进制流的方式传输
client.setFileType(FTP.BINARY_FILE_TYPE);
return true;
}
return false;
}
/**
* 连接FTP服务器
* @param client
* @param hostname
* @param port
* @param username
* @param password
* @return
*/
public static boolean tryConnect(FTPClient client, String hostname, int port, String username,
String password) {
Integer retry_index = retryIndexThreadLocal.get();
try {
if(retry_index == null) {
retry_index = 0;
retryIndexThreadLocal.set(retry_index);
}
if (retry_index > max_retry)
throw new Exception("Max connections exceeded");
return connect(client, hostname, port, username, password);
} catch (Exception e) {
e.printStackTrace();
String msg = e.getMessage();
if ("Max connections exceeded".equals(msg))
return false;
retryIndexThreadLocal.set(retry_index++);
try {
Thread.sleep(wait_time);
boolean con = tryConnect(client, hostname, port, username, password);
if(con)
retryIndexThreadLocal.set(0);
return con;
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
return false;
}
public static boolean uploadFile(FTPClient client, String remotePath, boolean cover, File localFile, Map<String, Object> params, FtpUploadFileCallback callback) throws Exception {
remotePath = remotePath.startsWith(File.separator) ? remotePath : File.separator + remotePath;
boolean cwd = client.changeWorkingDirectory(remotePath);
if (!cwd)
throw new Exception ("切换目录 ( " + remotePath + " ) 失败");
String fileName = localFile.getName();
//如果是覆盖文件则先删除原文件
if(cover && isExists(client, remotePath, fileName)) {
delete(client, fileName);
}
//上传文件
return resumeUploadFile(remotePath, localFile, client, params, callback);
}
/**
* 断点续传文件到ftp
* @param remoteFile Ftp服务器上当前文件名称
* @param localFile 本地文件,待上传文件
* @param ftpClient
* @throws Exception
* @throws IOException
*/
public static boolean resumeUploadFile(String remotePath, File localFile,FTPClient ftpClient, Map<String, Object> params, FtpUploadFileCallback callback) throws Exception {
long remoteFileSize = 0L;
RandomAccessFile raf = null;
BufferedOutputStream out = null;
String currentFileName = localFile.getName();
try{
//检查ftp服务器上是否已经存在此文件,且计算大小
/*if(isExists(ftpClient, remotePath,currentFileName)) {
FTPFile[] ftpFiles = ftpClient.listFiles(currentFileName);
if(ftpFiles != null && ftpFiles.length > 0) {
FTPFile ftpFile = ftpFiles[0];
remoteFileSize = ftpFile.getSize();
}
} */
long localFileSize = localFile.length();
//if(remoteFileSize >= localFileSize) {
// throw new Exception( " ( "+currentFileName + " ) 文件已经存在");
//}
raf = new RandomAccessFile(localFile, "r");
out = new BufferedOutputStream(ftpClient.appendFileStream(currentFileName));
if (remoteFileSize > 0) {
ftpClient.setRestartOffset(remoteFileSize);
raf.seek(remoteFileSize);
}
byte[] bytes = new byte[1024*1024*10];
int c = 0;
long uploadSize = remoteFileSize;
while ((c = raf.read(bytes))!= -1) {
out.write(bytes,0,c);
uploadSize += c;
try {
if(callback!=null)
callback.callback(remotePath, localFile, uploadSize, params);
}catch(Exception e) { }
}
//return ftpClient.completePendingCommand();
return true;
}catch(Exception e) {
throw new Exception(e.getMessage());
}
finally {
try {
if(out != null)
out.flush();
if(raf != null)
raf.close();
if(out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 删除文件
* @param client
* @param file
* @return
*/
public static boolean delete(FTPClient client, String file) {
try {
return client.deleteFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* 文件是否已经存在
* @param ftpClient
* @param currentFileName
* @return
*/
public static boolean isExists(FTPClient ftpClient, String currentFileName) {
return isExists(ftpClient, null, currentFileName);
}
public static boolean isExists(FTPClient ftpClient, String remoteFilePath, String currentFileName) {
try {
if(remoteFilePath != null && !"".equals(remoteFilePath)) {
boolean cwd = ftpClient.changeWorkingDirectory(remoteFilePath);
if(!cwd) return false;
}
String[] files = ftpClient.listNames();
if (files == null)
return false;
for (String fileName : files) {
if (fileName.equalsIgnoreCase(currentFileName))
return true;
}
} catch (IOException e1) {
e1.printStackTrace();
}
return false;
}
/**
* 断开与远程服务器的连接
*
* @throws IOException
*/
public static void disconnect(FTPClient client) throws IOException {
if (client.isConnected()) {
client.disconnect();
}
}
public static boolean isConnected(FTPClient client) {
return client.isConnected();
}
public static boolean isAvailable(FTPClient client) {
return client.isAvailable();
}
/**
* 创建目录
* @param ftpClient
* @param pathStr
* @return
*/
public static synchronized boolean createDirecroty(FTPClient ftpClient,String pathStr) {
try {
if (pathStr == null || "".equals(pathStr))
return true;
String[] paths = pathStr.split(File.separator);
for (String path : paths) {
boolean isExists = isExists(ftpClient, path);
if (isExists) {
ftpClient.changeWorkingDirectory(path);
} else {
boolean makdir = ftpClient.makeDirectory(path);
if (!makdir)
return false;
else
ftpClient.changeWorkingDirectory(path);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
interface FtpUploadFileCallback {
public void callback(String remotePath, File localFile, long uploadSize, Map<String, Object> params)throws Exception;
}
}
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.SocketException;
import java.util.Map;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
/**
* @author chc
* @version 创建时间:2014-7-17
* FTP上传工具类
*/
public class FtpClientUtil {
private static int max_retry = 999;//连接FTP不成功后,重试次数
private static long wait_time = 5000;//隔5秒后重新连接
private static final ThreadLocal<Integer> retryIndexThreadLocal = new ThreadLocal<Integer>();
public static boolean connect(FTPClient client, String hostname, int port, String username,
String password) throws SocketException, IOException {
client.setControlEncoding("UTF-8");
client.connect(hostname, port);
if (client.login(username, password)) {
// 设置PassiveMode传输
client.enterLocalPassiveMode();
// 设置以二进制流的方式传输
client.setFileType(FTP.BINARY_FILE_TYPE);
return true;
}
return false;
}
/**
* 连接FTP服务器
* @param client
* @param hostname
* @param port
* @param username
* @param password
* @return
*/
public static boolean tryConnect(FTPClient client, String hostname, int port, String username,
String password) {
Integer retry_index = retryIndexThreadLocal.get();
try {
if(retry_index == null) {
retry_index = 0;
retryIndexThreadLocal.set(retry_index);
}
if (retry_index > max_retry)
throw new Exception("Max connections exceeded");
return connect(client, hostname, port, username, password);
} catch (Exception e) {
e.printStackTrace();
String msg = e.getMessage();
if ("Max connections exceeded".equals(msg))
return false;
retryIndexThreadLocal.set(retry_index++);
try {
Thread.sleep(wait_time);
boolean con = tryConnect(client, hostname, port, username, password);
if(con)
retryIndexThreadLocal.set(0);
return con;
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
return false;
}
public static boolean uploadFile(FTPClient client, String remotePath, boolean cover, File localFile, Map<String, Object> params, FtpUploadFileCallback callback) throws Exception {
remotePath = remotePath.startsWith(File.separator) ? remotePath : File.separator + remotePath;
boolean cwd = client.changeWorkingDirectory(remotePath);
if (!cwd)
throw new Exception ("切换目录 ( " + remotePath + " ) 失败");
String fileName = localFile.getName();
//如果是覆盖文件则先删除原文件
if(cover && isExists(client, remotePath, fileName)) {
delete(client, fileName);
}
//上传文件
return resumeUploadFile(remotePath, localFile, client, params, callback);
}
/**
* 断点续传文件到ftp
* @param remoteFile Ftp服务器上当前文件名称
* @param localFile 本地文件,待上传文件
* @param ftpClient
* @throws Exception
* @throws IOException
*/
public static boolean resumeUploadFile(String remotePath, File localFile,FTPClient ftpClient, Map<String, Object> params, FtpUploadFileCallback callback) throws Exception {
long remoteFileSize = 0L;
RandomAccessFile raf = null;
BufferedOutputStream out = null;
String currentFileName = localFile.getName();
try{
//检查ftp服务器上是否已经存在此文件,且计算大小
/*if(isExists(ftpClient, remotePath,currentFileName)) {
FTPFile[] ftpFiles = ftpClient.listFiles(currentFileName);
if(ftpFiles != null && ftpFiles.length > 0) {
FTPFile ftpFile = ftpFiles[0];
remoteFileSize = ftpFile.getSize();
}
} */
long localFileSize = localFile.length();
//if(remoteFileSize >= localFileSize) {
// throw new Exception( " ( "+currentFileName + " ) 文件已经存在");
//}
raf = new RandomAccessFile(localFile, "r");
out = new BufferedOutputStream(ftpClient.appendFileStream(currentFileName));
if (remoteFileSize > 0) {
ftpClient.setRestartOffset(remoteFileSize);
raf.seek(remoteFileSize);
}
byte[] bytes = new byte[1024*1024*10];
int c = 0;
long uploadSize = remoteFileSize;
while ((c = raf.read(bytes))!= -1) {
out.write(bytes,0,c);
uploadSize += c;
try {
if(callback!=null)
callback.callback(remotePath, localFile, uploadSize, params);
}catch(Exception e) { }
}
//return ftpClient.completePendingCommand();
return true;
}catch(Exception e) {
throw new Exception(e.getMessage());
}
finally {
try {
if(out != null)
out.flush();
if(raf != null)
raf.close();
if(out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 删除文件
* @param client
* @param file
* @return
*/
public static boolean delete(FTPClient client, String file) {
try {
return client.deleteFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* 文件是否已经存在
* @param ftpClient
* @param currentFileName
* @return
*/
public static boolean isExists(FTPClient ftpClient, String currentFileName) {
return isExists(ftpClient, null, currentFileName);
}
public static boolean isExists(FTPClient ftpClient, String remoteFilePath, String currentFileName) {
try {
if(remoteFilePath != null && !"".equals(remoteFilePath)) {
boolean cwd = ftpClient.changeWorkingDirectory(remoteFilePath);
if(!cwd) return false;
}
String[] files = ftpClient.listNames();
if (files == null)
return false;
for (String fileName : files) {
if (fileName.equalsIgnoreCase(currentFileName))
return true;
}
} catch (IOException e1) {
e1.printStackTrace();
}
return false;
}
/**
* 断开与远程服务器的连接
*
* @throws IOException
*/
public static void disconnect(FTPClient client) throws IOException {
if (client.isConnected()) {
client.disconnect();
}
}
public static boolean isConnected(FTPClient client) {
return client.isConnected();
}
public static boolean isAvailable(FTPClient client) {
return client.isAvailable();
}
/**
* 创建目录
* @param ftpClient
* @param pathStr
* @return
*/
public static synchronized boolean createDirecroty(FTPClient ftpClient,String pathStr) {
try {
if (pathStr == null || "".equals(pathStr))
return true;
String[] paths = pathStr.split(File.separator);
for (String path : paths) {
boolean isExists = isExists(ftpClient, path);
if (isExists) {
ftpClient.changeWorkingDirectory(path);
} else {
boolean makdir = ftpClient.makeDirectory(path);
if (!makdir)
return false;
else
ftpClient.changeWorkingDirectory(path);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
interface FtpUploadFileCallback {
public void callback(String remotePath, File localFile, long uploadSize, Map<String, Object> params)throws Exception;
}
}