如何提高多个文件的ftp上载速度[Java]
我使用org.apache.commons.net.ftp.FTPClient实现了将文件上传到服务器的java代码 对于多个文件,ftp上载速度非常慢。 我怎样才能提高速度 -换图书馆? 什么是用于上载多个文件的功能强大的FTP客户端类库 -使用多线程? 如何使用多线程实现ftp上传功能? 有人能给我举个例子吗? 我是多线程编程的新手如何提高多个文件的ftp上载速度[Java],java,ftp,Java,Ftp,我使用org.apache.commons.net.ftp.FTPClient实现了将文件上传到服务器的java代码 对于多个文件,ftp上载速度非常慢。 我怎样才能提高速度 -换图书馆? 什么是用于上载多个文件的功能强大的FTP客户端类库 -使用多线程? 如何使用多线程实现ftp上传功能? 有人能给我举个例子吗? 我是多线程编程的新手 在我阅读了所有的答案之后,我试着修改我的代码并测试它 以下是FTP客户端代码示例: // create instance of FTPClient FTPCl
在我阅读了所有的答案之后,我试着修改我的代码并测试它 以下是FTP客户端代码示例:
// create instance of FTPClient
FTPClient ftp = new FTPClient();
ftp.setControlEncoding("UTF-8");
ftp.setDefaultTimeout(30000);
// connect to server
try
{
ftp.connect("10.1.1.1", 990);
}
catch(Exception e)
{
System.out.println("Cannot connect to server");
return;
}
// login to server
if (!ftp.login("username", "password"))
{
ftp.logout();
System.out.println("Cannot login to server");
return;
}
try
{
ftp.setFileTransferMode(FTP.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();
// ftp.setBufferSize(0); <-- someone suggest me to set buffer size to 0, but it throw error sometime.
}
catch(Exception e)
{
}
// create directory on server
// dirs is list of required directories on server
for (String dir : dirs)
{
try
{
ftp.makeDirectory(dir);
}
catch(IOException e)
{
}
}
// files is a map of local file and string of remote file
// such as
// file on client is "C://test/a.txt"
// location on server is "/test/a.txt"
for (Map.Entry<File, String> entry : files.entrySet())
{
File localFile = entry.getKey();
String remoteFile = entry.getValue();
FileInputStream input = null;
try
{
input= new FileInputStream(localFile);
ftp.storeFile(remoteFile, input);
}
catch (Exception e)
{
try
{
ftp.deleteFile(remoteFile);
}
catch (IOException e1)
{
}
}
finally
{
if (input != null)
{
try
{
input.close();
}
catch (IOException e)
{
}
}
}
}
// disconnect
if (ftp != null && ftp.isConnected())
{
try
{
ftp.disconnect();
}
catch (IOException f)
{
// do nothing
}
}
// create instance of FTPClient
FTPClient ftp = new FTPClient();
ftp.setCharset("UTF-8");
// connect to server
try
{
ftp.connect("10.1.1.1", 990);
}
catch(Exception e)
{
System.out.println("Cannot connect to server")
return;
}
// login to server
try
{
ftp.login("username", "password");
}
catch (Exception e)
{
try
{
ftp.logout();
}
catch (Exception e1)
{
}
System.out.println("Cannot login to server")
return;
}
try
{
ftp.setType(FTPClient.TYPE_BINARY);
ftp.setPassive(true);
}
catch(Exception e)
{
}
// create directory on server
// dirs is list of required directories on server
for (String dir : dirs)
{
try
{
ftp.createDirectory(dir);
}
catch (Exception e)
{
}
}
// files is a map of local file and string of remote file
// such as
// file on client is "C://test/a.txt"
// location on server is "/test/a.txt"
for (Map.Entry<File, String> entry : files.entrySet())
{
final File localFile = entry.getKey();
final String remoteFile = entry.getValue();
BufferedInputStream input = null;
boolean success = false;
try
{
input = new BufferedInputStream(new FileInputStream(localFile));
// ftp.upload(localFile); <-- if I use ftp.upload(File), it will took more time.
ftp.upload(remoteFile, input, 0, 2048, new MyTransferListener());
success = true;
}
catch (Exception e)
{
}
finally
{
if (input != null)
{
try
{
input.close();
}
catch (IOException e)
{
}
}
if (!success)
{
try
{
ftp.deleteFile(remoteFile);
}
catch (Exception e)
{
}
}
}
}
// disconnect
if (ftp != null && ftp.isConnected())
{
try
{
ftp.disconnect();
}
catch (IOException f)
{
// do nothing
}
}
//创建FTPClient的实例
FTPClient ftp=新的FTPClient();
ftp.setControlEncoding(“UTF-8”);
ftp.setDefaultTimeout(30000);
//连接到服务器
尝试
{
ftp.connect(“10.1.1.1”,990);
}
捕获(例外e)
{
System.out.println(“无法连接到服务器”);
返回;
}
//登录到服务器
如果(!ftp.login(“用户名”、“密码”))
{
ftp.logout();
System.out.println(“无法登录到服务器”);
返回;
}
尝试
{
setFileTransferMode(ftp.BINARY\u文件类型);
ftp.enterLocalPassiveMode();
//setBufferSize(0);我不知道为什么,但是ApacheCommons ftp上传速度非常慢,我遇到了同样的问题,无法解决
现在我使用的是,它非常类似于ApacheCommonsFTP,但上传速度非常快
这是一个例子:
FTPClient client=new FTPClient();
client.connect(“www.yoursite.com”);
客户端登录(“登录”、“密码”);
client.setPassive(true);
setType(FTPClient.TYPE_二进制文件);
客户。变更目录(“a”);
文件f=新文件(“路径/到/您的/文件”);
客户端。上传(f);
client.disconnect(true);
使用这个库,我在不到一秒钟的时间内上传了一个340KB的文件,而使用ApacheCommonsFTP大约需要1分钟
如果您想使用线程传输不同的文件,请尝试将每个客户端.upload(f)
放在不同的线程中,但我不确定它是否会提高传输速度
引用@fge先前的答案:
基本上,机会是,你不能
不要忘记FTP有两种通道:命令通道和数据通道。一种上传是通过在命令通道上发送指令来启动的,为上传打开一个数据通道
现在:
- 大多数FTP服务器配置为一个命令通道在任何时候只能打开一个数据通道
- 存在带宽限制:您的上游带宽和服务器的下游带宽
如果有可能并行上传多个文件,即打开多个数据通道,那么TCP本身的开销通常会减慢上传过程
基本上:随时打开一个数据通道。尝试并打开多个数据通道是不值得的。一般情况下,这可能在约1%的情况下有效。这不值得麻烦。本问答提供了一些可能的解释:
此外,它还提供了两种变通方法:
- 升级到(当前)可以找到的3.3快照
- 调用FTPClient.setBufferSize(0)
显然,Java 7 for Windows中也存在一种倒退,FTP客户端的防火墙应用程序过滤器阻止客户端使用PASV模式FTP。目前还不清楚最好的解决方案是什么,但您可以尝试以下方法:
- 更改Windows防火墙以禁用防火墙应用程序筛选器(如Microsoft KB页中所述)
- 将FTP应用程序更改为使用“活动”模式…尽管这要求FTP服务器可以启动与运行客户端的计算机的连接
注意:对于这个问题似乎有不止一种解释……或者可能有不止一种可能的问题。我建议你首先找出上传速度慢的原因。这就是你应该改变的答案,以加快上传速度。你应该先熟悉这些概念。举个例子(他们不会知道你是如何储存你的东西的)可能会导致同步问题和难以跟踪错误。您的程序会正常工作,但不是您想要的方式。如果服务器限制最大上载速率,并允许您一次上载多个文件,请使用不同的代理(如果可能),并且服务器限制每个系统上载一个文件上传来隐藏你的IPDefine很慢。为什么要更快呢?关于另一个库,这是一个很好的建议!但是,正如我在回答中所解释的,一次上传多个文件往往会适得其反……将我的答案合并到你的答案中,我将删除我的答案?@fge是的,最后一行是说事实上上传了更多的文件同时会降低上传速度。将我的答案合并到你的答案中,我会删除我的答案。你是说将你的答案完全复制到我的答案吗?“花了一分钟”听起来像是其他东西坏了。具体花了多少时间?@Thorbjørnravandersen当我调用
client.storeFile()时,我测量了时间
从Apache Commons上传非常小的文件需要一分钟的时间。当我从FTP4j调用client.upload()
时,传输同样的文件需要1-2秒file@Thorbjørnravandersen不是System.currentTimeMillis()
之间的区别(首先在调用upload函数之前进行,然后在它之后进行调用)默认情况下,enaugh?@fge FTPClient使用1KB的缓冲区上载文件,这使得上载速度非常慢。如果将缓冲区大小更改为0,它应该使用它可以使用的最大缓冲区大小。但是,我尝试将缓冲区大小设置为0,但这并没有提高上载速度。也可能该问题的某些答案是错误的。…或应用于不同的场景。我只是报告我在
final CountDownLatch latch = new CountDownLatch(files.size());
ExecutorService pool = Executors.newFixedThreadPool(10);
for (Map.Entry<File, String> entry : files.entrySet())
{
final File localFile = entry.getKey();
final String remoteFile = entry.getValue();
pool.execute(new Runnable() {
public void run()
{
FileInputStream input = null;
try
{
input= new FileInputStream(localFile);
ftp.storeFile(remoteFile, input);
}
catch (Exception e)
{
try
{
ftp.deleteFile(remoteFile);
}
catch (IOException e1)
{
}
}
finally
{
if (input != null)
{
try
{
input.close();
}
catch (IOException e)
{
}
}
latch.countDown();
}
}
});
}
try
{
// waiting for all threads finish
// see: http://stackoverflow.com/questions/1250643/how-to-wait-for-all-threads-to-finish-using-executorservice
latch.await();
}
catch(Exception e)
{
}