使用JSch从SFTP下载多个文件失败并显示“请求队列:未知请求问题”

时间:2018-01-16 19:41:36

标签: java sftp jsch downloadfile

我正在尝试从FTP服务器下载多个文件。当我简单地通过for循环时,它工作正常。我不知道文件大小可能会有所不同,可能太小或太大。所以,我正在使用执行器服务下载它们。当我通过执行程序放置下载功能时,我得到请求队列:未知的请求问题。请让我知道我哪里出错了。

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();

这是下载程序类

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();
            }
        }

    }

}

这是错误

java.io.IOException: error: 4: RequestQueue: unknown request id 1399811183
    at com.jcraft.jsch.ChannelSftp$2.read(ChannelSftp.java:1406)
    at java.io.BufferedInputStream.fill(Unknown Source)
    at java.io.BufferedInputStream.read1(Unknown Source)
    at java.io.BufferedInputStream.read(Unknown Source)
    at java.io.FilterInputStream.read(Unknown Source)
    at com.shipmentprocessing.network.FTPConnector$FileDownloader.run(FTPConnector.java:141)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
java.io.IOException: error
    at com.jcraft.jsch.ChannelSftp$2.close(ChannelSftp.java:1505)
    at java.io.BufferedInputStream.close(Unknown Source)
    at com.shipmentprocessing.network.FTPConnector$FileDownloader.run(FTPConnector.java:150)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

1 个答案:

答案 0 :(得分:0)

虽然您可以使用一个SFTP连接/ JSch会话进行多次下载,但JSch会话绝对不是线程安全的。

因此,如果您需要运行下载是单独的线程,则必须为(in)每个线程打开新连接。您的下载性能也会更好。