Java 使用JSch从SFTP下载多个文件失败;请求队列:未知请求问题“;
我正在尝试从FTP服务器下载多个文件。当我简单地通过for循环时,它工作得很好。我不知道文件大小可能不同,可能太小或太大。所以,我使用executor服务下载它们。当我将下载功能通过executor时,我得到了请求队列:未知请求问题。请告诉我哪里出了问题Java 使用JSch从SFTP下载多个文件失败;请求队列:未知请求问题“;,java,sftp,jsch,downloadfile,Java,Sftp,Jsch,Downloadfile,我正在尝试从FTP服务器下载多个文件。当我简单地通过for循环时,它工作得很好。我不知道文件大小可能不同,可能太小或太大。所以,我使用executor服务下载它们。当我将下载功能通过executor时,我得到了请求队列:未知请求问题。请告诉我哪里出了问题 System.out.println("Connecting to FTP Server"); Session session = null; ChannelSftp channelSftp = null; JSch jsch = new J
System.out.println("Connecting to FTP Server");
Session session = null;
ChannelSftp channelSftp = null;
JSch jsch = new JSch();
session = jsch.getSession(sftpUser,sftpHost,22);
session.setPassword(sftpPassword);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
System.out.println("Session Connected Status: "+session.isConnected());
Channel channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp)channel;
System.out.println("Channel Connected Status: "+channelSftp.isConnected());
System.out.println("File: "+sourceFilePath);
if(channelSftp.isConnected())
{
String path = this.propertyManager.getValue("targetDirectoryPath");
channelSftp.cd(path);
Vector filelist = channelSftp.ls(path);
for(int i=0; i<filelist.size();i++)
{
LsEntry entry = (LsEntry) filelist.get(i);
String fileName = sourceFilePath + entry.getFilename();
destinationFilePath = ShipmentUtils.getDownloadPath(entry.getFilename());
System.err.println(entry.getFilename());
exec.execute(new FileDownloader(destinationFilePath, channelSftp.get(fileName)));
}
}
channelSftp.disconnect();
session.disconnect();
这就是错误所在
java.io.IOException:错误:4:请求队列:未知请求id 1399811183
com.jcraft.jsch.ChannelSftp$2.read(ChannelSftp.java:1406)
位于java.io.BufferedInputStream.fill(未知源)
位于java.io.BufferedInputStream.read1(未知源)
位于java.io.BufferedInputStream.read(未知源)
位于java.io.FilterInputStream.read(未知源)
位于com.shipmentprocessing.network.FTPConnector$FileDownloader.run(FTPConnector.java:141)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(未知源)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(未知源)
位于java.lang.Thread.run(未知源)
java.io.IOException:错误
com.jcraft.jsch.ChannelSftp$2.close(ChannelSftp.java:1505)
位于java.io.BufferedInputStream.close(未知源)
位于com.shipmentprocessing.network.FTPConnector$FileDownloader.run(FTPConnector.java:150)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(未知源)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(未知源)
位于java.lang.Thread.run(未知源)
虽然可以使用一个SFTP连接/JSch会话进行多次下载,但JSch会话绝对不是线程安全的
因此,如果需要在单独的线程中运行下载,则必须为每个线程打开新连接。这样您的下载性能也会更好。您没有准确地引用错误消息。这就是我得到的错误。您正在打开一个连接,并通过此连接同时请求多个文件。我希望您应该为要下载的每个文件打开一个新连接。查看此链接我打开连接,检查可供下载的文件数量,并保持逐个下载。但是为什么要再次打开多个连接并重新阅读文档呢?您应该为每个要下载的文件打开一个新的通道。
private class FileDownloader implements Runnable
{
String destinationFilePath;
InputStream stream;
public FileDownloader(String destinationFilePath , InputStream stream) {
this.destinationFilePath = destinationFilePath;
this.stream = stream;
}
@Override
public void run() {
byte[] buffer = new byte[1024];
BufferedOutputStream bos = null;
BufferedInputStream bis = null ;
try
{
bis = new BufferedInputStream(stream);
File newFile = new File(destinationFilePath);
OutputStream os = new FileOutputStream(newFile);
bos = new BufferedOutputStream(os);
int readCount=0;
while( (readCount = bis.read(buffer)) > 0) {
bos.write(buffer, 0, readCount);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if(bis != null) bis.close();
if(bos != null) bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}