Transmissão FTP muito lenta no java

Bom dia,

Tenho uma aplicação em java que transfere arquivos para o FTP.
Porém essa transferência é muito lenta, tipo, um arquivo de 20 mb leva em torno de 30 minutos para subir.
Eu peguei esse mesmo arquivo e subi no mesmo ftp na mesma rede, no mesmo ambiente, só que utilizando o Filezilla e transferiu em 2 minutos.
Qual é a Mágica que ele faz? Será que não consigo fazer isso no meu fonte em java?

Segue abaixo a classe que faz upload pro ftp.

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.UnknownHostException;
import java.rmi.ConnectException;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

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.io.CopyStreamAdapter;

import br.com.backupsafe.conexaows.ConexaoWs;
import br.com.backupsafe.generic.config.Config;
import br.com.backupsafe.generic.debug.Debug;
import br.com.backupsafe.generic.exception.FTPException;
import br.com.backupsafe.generic.exception.NoXmlConfigException;
import br.com.backupsafe.generic.framework.conexaobd.sqllite.ConexaoSqlLite;
import br.com.backupsafe.generic.framework.utils.DateUtils;

public class FtpUtils  implements IFtp{


	private static FTPClient ftp;
	private static FtpUtils ftpUtils;

	private String host;
	private Integer port;
	private String username;
	private String password;
	private int percent = 0;

	private String dir;

	public boolean iniciaFtp() throws FTPException {
		try{

			ftp = new FTPClient();

			ftp.connect(this.host, this.port);

			if(ftp.login(this.username, this.password) == false){					
				throw new FTPException("Nao foi possivel conectar! \n" +ftp.getReplyString());						
			}else{
				Debug.imprimir(DateUtils.formataDataLog(new Date())	+" - Conectado ao FTP com sucesso!");
			};

			if(dir!= null && !dir.isEmpty()){
				ftp.makeDirectory(dir);
				ftp.changeWorkingDirectory(dir);
			}

			ftp.enterLocalPassiveMode();
			//			ftp.setFileTransferMode(FTP.BLOCK_TRANSFER_MODE);
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			
			
			return true;
		}catch(UnknownHostException e){
			throw new FTPException("Nao foi possivel conectar ao FTP (Host invalido)", e);
		}catch(ConnectException e){
			throw new FTPException("Nao foi possivel conectar ao FTP (Conexao interrompida)", e);
		} catch (IOException e) {
			throw new FTPException(e);
		}
	}

	public static FtpUtils getInstance() {
		if (ftpUtils == null) {
			ftpUtils = new FtpUtils();
		}
		return ftpUtils;
	}


	private boolean uploadArquivo(final File file, String nome,final String cnpj) throws FTPException {

		try {

			// 1 - StoreFile 2 - StoreFileStream
			Integer metodo = 1;
			boolean completed = false;

			boolean ok = this.iniciaFtp();
			
			
			CopyStreamAdapter streamListener = new CopyStreamAdapter() {
				

				@Override
				public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
					int perc = (int) (totalBytesTransferred * 100 / file.length());
					if(perc != getPercent()){
						setPercent(perc);
						
						Debug.printUpload("Percentual de upload: "+ getPercent()+" %.");
					}
				}
			};

			ftp.setCopyStreamListener(streamListener);
			
			if(ok){
				
				ftp.makeDirectory(cnpj);
				ftp.changeWorkingDirectory(cnpj);

				Debug.imprimir(DateUtils.formataDataLog(new Date())	+" - Fazendo upload de arquivo para o FTP ("+this.host +" "+ this.port+" "+  this.dir + ")");
				String localFileName = file.getAbsolutePath();

				FileInputStream in = new FileInputStream(localFileName);

				if(metodo == 1){
					completed = ftp.storeFile(nome, in);
					in.close();		

				}else{

					byte[] buffer = new byte[4096];
					OutputStream out = ftp.storeFileStream(nome);
					while (true) {
						int bytes = in.read(buffer);				

						if (bytes < 0)
							break;
						out.write(buffer, 0, bytes);
					}			
					in.close();
					out.close();

					completed = ftp.completePendingCommand();
				}
				Debug.imprimir(DateUtils.formataDataLog(new Date())	+" - Arquivo enviado com sucesso!");
			}
			return completed;

		}catch(IOException e){
			throw new FTPException(e);
		}finally {

			try {
				if(ftp!= null){
					ftp.logout();
					ftp.disconnect();
				}
			} catch (IOException e) {
				throw new FTPException(e);
			}
		}
	}


	public FTPClient getFtp(){
		return ftp;
	}

	public boolean enviaArquivoParaFtp(String arqZip, File arqBackupZip,String cnpj) throws NoXmlConfigException, FTPException{

		for (int i = 1; i <= Config.getInstance().getQtdTentativas(); i++) {

			Boolean ok = false;
			Debug.imprimir(DateUtils.formataDataLog(new Date())	+" - "+i+" tentativa de enviar ao FTP!");
			/*
			 *  Upload
			 */
			try{

				Debug.imprimir(DateUtils.formataDataLog(new Date())	+" - Fazendo upload do arquivo: "+arqZip+"... Tamanho: "+arqBackupZip.length());			

				ok = this.uploadArquivo(arqBackupZip, arqZip,cnpj);
				return ok;


			}catch(FTPException e){

				if (i == Config.getInstance().getQtdTentativas()){
					throw e;
				}							
			}
			if(ok){
				return ok;
			}
		}
		return false;
	}

	@Override
	public void setHost(String hostFtp) {
		this.host = hostFtp;		
	}

	@Override
	public void setPort(Integer portaFtp) {
		this.port = portaFtp;		
	}

	@Override
	public void setUsername(String userFtp) {
		this.username = userFtp;
	}

	@Override
	public void setPassword(String passwordDecrypt) {
		this.password = passwordDecrypt;

	}

	@Override
	public void setDir(String diretorioFtp) {
		this.dir = diretorioFtp;
	}

	public int getPercent() {
		return percent;
	}

	public void setPercent(int percent) {
		this.percent = percent;
	}
}

Obrigado!

Aumenta o buffer do seu FTPClient, abaixo um exemplo com buffer de 1MB:

ftp.setBufferSize(1048576);

@staroski Deu certo a sua solução, muito obrigado!
De 30 minutos ele caiu para menos de 2 minutos!

Show de bola! :grinning::grinning::grinning:

Abraços!

1 curtida