Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JSch从SFTP下载多个文件失败;请求队列:未知请求问题“;_Java_Sftp_Jsch_Downloadfile - Fatal编程技术网

Java 使用JSch从SFTP下载多个文件失败;请求队列:未知请求问题“;

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

我正在尝试从FTP服务器下载多个文件。当我简单地通过for循环时,它工作得很好。我不知道文件大小可能不同,可能太小或太大。所以,我使用executor服务下载它们。当我将下载功能通过executor时,我得到了请求队列:未知请求问题。请告诉我哪里出了问题

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

    }

}