SFTP:使用java读取文件时发生IOException

SFTP:使用java读取文件时发生IOException,java,apache-poi,sftp,jsch,Java,Apache Poi,Sftp,Jsch,我正在使用com.jcraft.jsch库从SFTP服务器读取.xls文件。以下是连接到服务器的代码 session = jsch.getSession(username, host); session.setConfig("StrictHostKeyChecking", "no"); session.setPassword(password); session.connect(); sftpChannel = (ChannelSftp) session.

我正在使用com.jcraft.jsch库从SFTP服务器读取.xls文件。以下是连接到服务器的代码

    session = jsch.getSession(username, host);
    session.setConfig("StrictHostKeyChecking", "no");
    session.setPassword(password);
    session.connect();
    sftpChannel = (ChannelSftp) session.openChannel("sftp");
    sftpChannel.connect();
我正在使用sftpChannel.getfile检索文件的inputStream。然后使用此inputstream实例化XSSFWorkbook,如下所示:

XSSFWorkbook workbook = new XSSFWorkbook(in);
问题1:

当我运行应用程序时,它似乎在上面的行上停留了一段时间,比如说5分钟,然后它抛出java.io.IOException:Pipe closed error。 我试图读取的xls文件是800kb,从本地计算机运行时工作正常

问题2:

该应用程序旨在按顺序处理文件。所以,如果第一个文件在IOE中失败,其余文件也会在连接超时时失败。为了防止出现这种情况,我使用以下代码进行检查并重新连接:

if(null == session || !session.isConnected()){
        log.debug("Session is not connected/timed out. Creating a new session");
        openSftpSession();
        log.debug("New session is created");
    }
//openSftpSession() is the code to create a new session as explained in the beginning of the question.
执行此代码时,会引发以下异常:

java.io.IOException: error: 4: RequestQueue: unknown request id 1028332337
    at com.jcraft.jsch.ChannelSftp$2.read(ChannelSftp.java:1407)
    at java.io.FilterInputStream.read(FilterInputStream.java:133)
    at java.io.PushbackInputStream.read(PushbackInputStream.java:186)
//More lines
编辑:检索输入流的代码

public InputStream getInputStream(String folder, String file) throws Exception{
    sftpChannel.cd(root + folder);
    log.debug("current directory:" + sftpChannel.pwd());
    log.debug("File :" + folder + " " + file);
    return sftpChannel.get(file);
}
有谁能帮我克服这一点吗?我认为防止超时的另一种方法是在某个临时目录和进程中下载文件。然而,我真的不想这么做


提前感谢。

您是否检查过您描述的下载到临时文件的方法是否有效?只是为了验证您的inputstream是否正常。。通过该连接下载到本地文件需要多长时间

如果你不想管理一个临时文件,你可以把它放到内存中的一个字节[],只要你不需要扩展到800kbs以上。。使用Apache Commons,如下所示:


至于请求Id,看起来旧会话/通道仍在尝试读取,但无法再读取。可能您没有正确关闭该会话/频道。从openSftpSession代码看,您似乎只会覆盖引用,而不会正确关闭它们。

感谢@Brendan的回复,我刚刚将连接的aliveInterval设置为60000,即每分钟设置一次活动ping。现在,它并没有超时,但似乎要花很长时间!已经超过35分钟了,XSSF工作簿还没有创建!我可以通过单线程对请求id进行排序。是的,让我尝试一下将数据存储到字节数组中的方法。希望它不会造成记忆问题;只要您有足够的虚拟内存,就可以将文件内容存储在字节数组中。您是否可以编辑问题,将调用sftpChannel.get的代码和触发异常的代码包括在内?新的XSSFWorkbook实际上是从远程服务器获取任何数据,还是只是在第一次读取时阻塞,直到超时?在连接超时之前,它实际上从远程服务器读取了多少数据?我已经添加了获取输入流的代码。我正在获取输入流,当我打印时,它将打印0。而且,我相信。阅读挂起。我尝试了Brendan建议的解决方案,但现在它挂起在IOUtils.toByteArray方法上。我已将保持活动时间设置为1分钟,因此连接现在不会超时。然而,它永远挂在阅读上。
InputStream in = sftpChannel.get(file);
byte[] inBytes = org.apache.commons.io.IOUtils.toByteArray(in)
ByteArrayInputStream inByteStream = new ByteArrayInputStream(inBytes)
XSSFWorkbook workbook = new XSSFWorkbook(inByteStream);