ftp并发上传失败解决方法

时间:2018-10-30

ftp并发上传失败是一个比较麻烦的问题,十几个同时上传或者下载文件会出现限制,小编今天给大家带来了详细的解决方法,需要的快点来看看吧。

ftp并发上传失败解决方法:

首先需要一个结构体

这个结构体应当拥有

(1)源文件的句柄

(2)目标文件的句柄

(3)写文件的起始位置

(4)写文件的终止位置

每一个结构体代表了文件的一部分

如果说把文件分成了5份,那就应该定义5个结构体,然后求出文件的大小,把文件的大小分成五份,

然后记录这一部分应当从文件的何处拷贝到何处,以及目标文件和源文件的句柄

开始定义线程内的函数,通过lseek函数找到应当找到的位置

然后开始拷贝就好了

package com.ourpalm.resupgrade.util.ftp;

import java.io.BufferedInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.UnknownHostException;

import org.apache.commons.net.ftp.FTPClient;

import org.apache.commons.net.ftp.FTPReply;

import com.ourpalm.resupgrade.config.FtpConfig;

/**

* FTP 连接

* @author chuer

* @date 2015年1月7日 下午2:19:48

*/

public class FtpConnection {

public static final String ANONYMOUS_LOGIN = "anonymous";

private FTPClient ftp = new FTPClient();

private boolean is_connected = false;

/**

* 构造函数

*/

public FtpConnection(){

is_connected = false;

ftp.setDefaultTimeout(FtpConfig.defaultTimeoutSecond * 1000);

ftp.setConnectTimeout(FtpConfig.connectTimeoutSecond * 1000);

ftp.setDataTimeout(FtpConfig.dataTimeoutSecond * 1000);

try {

initConnect(FtpConfig.host,FtpConfig.port,FtpConfig.user,FtpConfig.password);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 初始化连接

* @param host

* @param port

* @param user

* @param password

* @throws IOException

*/

private void initConnect(String host, int port, String user, String password) throws IOException {

try {

ftp.connect(host, port);

} catch (UnknownHostException ex) {

throw new IOException("Can't find FTP server '" + host + "'");

}

int reply = ftp.getReplyCode();

if (!FTPReply.isPositiveCompletion(reply)) {

disconnect();

throw new IOException("Can't connect to server '" + host + "'");

}

if (user == "") {

user = ANONYMOUS_LOGIN;

}

if (!ftp.login(user, password)) {

is_connected = false;

disconnect();

throw new IOException("Can't login to server '" + host + "'");

} else {

is_connected = true;

}

}

/**

* 上传文件

* @param path

* @param ftpFileName

* @param localFile

* @throws IOException

*/

public void upload(String path,String ftpFileName, File localFile) throws IOException {

//检查本地文件是否存在

if (!localFile.exists()) {

throw new IOException("Can't upload '" + localFile.getAbsolutePath() + "'. This file doesn't exist.");

}

//设置工作路径

setWorkingDirectory(path);

//上传

InputStream in = null;

try {

//被动模式

ftp.enterLocalPassiveMode();

in = new BufferedInputStream(new FileInputStream(localFile));

//保存文件

if (!ftp.storeFile(ftpFileName, in)) {

throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path.");

}

} finally {

try {

in.close();

} catch (IOException ex) {

}

}

}

/**

* 关闭连接

* @throws IOException

*/

public void disconnect() throws IOException {

if (ftp.isConnected()) {

try {

ftp.logout();

ftp.disconnect();

is_connected = false;

} catch (IOException ex) {

ex.printStackTrace();

}

}

}

/**

* 设置工作路径

* @param dir

* @return

*/

private boolean setWorkingDirectory(String dir) {

if (!is_connected) {

return false;

}

//如果目录不存在创建目录

try {

if(createDirecroty(dir)){

return ftp.changeWorkingDirectory(dir);

}

} catch (IOException e) {

e.printStackTrace();

}

return false;

}

/**

* 是否连接

* @return

*/

public boolean isConnected(){

return is_connected;

}

/**

* 创建目录

* @param remote

* @return

* @throws IOException

*/

private boolean createDirecroty(String remote) throws IOException {

boolean success = true;

String directory = remote.substring(0, remote.lastIndexOf("/") + 1);

// 如果远程目录不存在,则递归创建远程服务器目录

if (!directory.equalsIgnoreCase("/") && !ftp.changeWorkingDirectory(new String(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 (!ftp.changeWorkingDirectory(subDirectory)) {

if (ftp.makeDirectory(subDirectory)) {

ftp.changeWorkingDirectory(subDirectory);

} else {

System.out.println("mack directory error :/"+subDirectory);

return false;

}

}

start = end + 1;

end = directory.indexOf("/", start);

// 检查所有目录是否创建完毕

if (end <= start) {

break;

}

}

}

return success;

}

}

package com.ourpalm.resupgrade.util.ftp;

import java.io.IOException;

import java.util.concurrent.ArrayBlockingQueue;

import com.ourpalm.resupgrade.config.FtpConfig;

/**

* 连接工厂

* @author chuer

* @date 2015年1月7日 下午2:32:22

*/

public class FtpFactory {

private final ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(FtpConfig.ftpConnectionSize);

protected FtpFactory(){

System.out.println("init FtpFactory");

for(int i=0;i< FtpConfig.ftpConnectionSize; i++){

arrayBlockingQueue.offer(new FtpConnection());

}

}

/**

* 获取连接

* @return

*/

public FtpConnection getFtp(){

FtpConnection poll = null;

try {

poll = arrayBlockingQueue.take();

} catch (InterruptedException e) {

e.printStackTrace();

}

return poll;

}

/**

* 释放连接

* @param ftp

* @return

*/

public boolean relase(FtpConnection ftp){

return arrayBlockingQueue.offer(ftp);

}

/**

* 删除连接

* @param ftp

*/

public void remove(FtpConnection ftp){

arrayBlockingQueue.remove(ftp);

}

public void close(){

for(FtpConnection connection : arrayBlockingQueue){

try {

connection.disconnect();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

package com.ourpalm.resupgrade.util.ftp;

import java.io.File;

import java.io.IOException;

import java.util.concurrent.Callable;

import com.ourpalm.resupgrade.util.log.LoggerUtils;

/**

* 上传任务

* @author chuer

* @date 2015年1月7日 下午2:30:46

*/

public class UploadTask implements Callable{

private File file;

private FtpConnection ftp;

private String path;

private String fileName;

private FtpFactory factory;

public UploadTask(FtpFactory factory,FtpConnection ftp,File file,String path,String fileName){

this.factory = factory;

this.ftp = ftp;

this.file = file;

this.path = path;

this.fileName = fileName;

}

@Override

public UploadResult call() throws Exception {

UploadResult result = null;

try{

if(ftp == null){

result = new UploadResult(file.getAbsolutePath(),false);

return result;

}

//如果连接未开启 重新获取连接

if(!ftp.isConnected()){

factory.remove(ftp);

ftp = new FtpConnection();

// factory.relase(ftp);

}

//开始上传

LoggerUtils.upload.info(file.getName()+" is uploading ...");

FtpResult.resultList.add(file.getName()+" is uploading ...");

ftp.upload(path, fileName, file);

result = new UploadResult(file.getName(),true);

}catch(IOException ex){

result = new UploadResult(file.getName(),false);

ex.printStackTrace();

}finally{

factory.relase(ftp);//释放连接

}

FtpResult.resultList.add(result.toString());

LoggerUtils.upload.info(result.toString());

return result;

}

}

package com.ourpalm.resupgrade.util.ftp;

/**

* 上传结果

* @author chuer

* @date 2015年1月7日 下午2:31:14

*/

public class UploadResult {

private String fileName; //文件名称

private boolean result; //是否上传成功

public UploadResult(String fileName,boolean result){

this.fileName = fileName;

this.result = result;

}

public String getFileName() {

return fileName;

}

public void setFileName(String fileName) {

this.fileName = fileName;

}

public boolean isResult() {

return result;

}

public void setResult(boolean result) {

this.result = result;

}

public String toString(){

return "[fileName="+fileName+" , result="+result+"]";

}

}

package com.ourpalm.resupgrade.util.ftp;

import java.util.List;

import java.util.concurrent.CopyOnWriteArrayList;

/**

* 实时上传结果

* @author chuer

* @date 2015年1月7日 下午4:57:24

*/

public class FtpResult {

public static List resultList = new CopyOnWriteArrayList<>();

}

package com.ourpalm.resupgrade.util.ftp;

import java.io.File;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

import java.util.concurrent.TimeUnit;

import com.ourpalm.resupgrade.config.FtpConfig;

/**

* ftp上传工具包

* @author chuer

* @date 2015年1月7日 下午2:31:39

*/

public class FtpUtil {

/**

* 上传文件

* @param ftpPath

* @param listFiles

* @return

*/

public static synchronized List upload(String ftpPath,File [] listFiles) {

ExecutorService newFixedThreadPool = Executors .newFixedThreadPool(FtpConfig.threadPoolSize);

List> results = new ArrayList<>();

FtpFactory factory = new FtpFactory();

for (File file : listFiles) {

FtpConnection ftp = factory.getFtp();

UploadTask upload = new UploadTask(factory,ftp, file, ftpPath, file.getName());

Future submit = newFixedThreadPool.submit(upload);

results.add(submit);

}

List listResults = new ArrayList<>();

for (Future result : results) {

try {

UploadResult uploadResult = result.get(30, TimeUnit.MINUTES);

listResults.add(uploadResult);

} catch (Exception e) {

e.printStackTrace();

}

}

factory.close();

newFixedThreadPool.shutdown();

return listResults;

}

}

package com.ourpalm.resupgrade.config;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import com.ourpalm.resupgrade.util.io.XmlUtils;

/**

* ftp 配置类

* @author chuer

* @date 2015年1月7日 下午4:36:50

*/

public class FtpConfig {

public static int defaultTimeoutSecond;

public static int connectTimeoutSecond;

public static int dataTimeoutSecond;

public static String host;

public static int port;

public static String user;

public static String password;

public static int threadPoolSize;

public static int ftpConnectionSize;

public static String rootPath;

/**

* @param path

*/

public static void load(String path) {

path += "ftpConfig.xml";

try{

Document doc = XmlUtils.load(path);

Element root = doc.getDocumentElement();

defaultTimeoutSecond = Integer.parseInt(XmlUtils.getChildText(root, "defaultTimeoutSecond"));

connectTimeoutSecond = Integer.parseInt(XmlUtils.getChildText(root, "connectTimeoutSecond"));

dataTimeoutSecond = Integer.parseInt(XmlUtils.getChildText(root, "dataTimeoutSecond"));

host = XmlUtils.getChildText(root, "host");

port = Integer.parseInt(XmlUtils.getChildText(root, "port"));

user = XmlUtils.getChildText(root, "user");

password = XmlUtils.getChildText(root, "password");

threadPoolSize = Integer.parseInt(XmlUtils.getChildText(root, "threadPoolSize"));

ftpConnectionSize = Integer.parseInt(XmlUtils.getChildText(root, "ftpConnectionSize"));

rootPath = XmlUtils.getChildText(root, "rootPath");

}catch(Exception e){

e.printStackTrace();

}

}

}

package com.ourpalm.resupgrade.util.ftp;

import java.io.File;

import java.io.IOException;

import java.util.List;

/**

* 客户端

* @author chuer

* @date 2015年1月7日 下午2:32:41

*/

public class Client {

public static void main(String[] args) throws IOException {

String loalPath = "D:/resource/";

String ftpPath = "/resource";

File parentFile = new File(loalPath);

List resultLists = FtpUtil.upload(ftpPath,parentFile.listFiles());

for(UploadResult result : resultLists){

System.out.println(result);

}

}

}