gpt4 book ai didi

java - 为什么 JSch ChannelSftp 返回 "Handle closed"?

转载 作者:行者123 更新时间:2023-12-02 12:05:40 26 4
gpt4 key购买 nike

我正在使用 jsch 0.1.54,我正在尝试通过 SFTP 访问 FTP 服务器。这一切正常,我能够进入所需的目录,但是当我使用执行 Channel.ls("*"); 的模式获取文件时,我只得到第一个匹配项,并且对于下一个我得到一个“句柄已关闭”,但不是文件名。为什么?

更准确地说,当我最终到达所需的目录时,我执行了

sftp.ls(ftpAccount + File.separator + lsEntry.getFilename() +
File.separator + "*", new ChannelSftp.LsEntrySelector() {...});

也许 LsEntrySelectore 是“句柄关闭”的原因!?

该方法的完整代码如下:

   public Map<String, byte[]> readFiles () {
final Map<String, byte[]> vaFiles = new HashMap();
final Channel channel;
try {
channel = session.openChannel("sftp");
channel.connect();
final List<String> ftpAccounts = Arrays.stream(this.ftpAccounts).collect(Collectors.toList());
for (final String ftpAccount : ftpAccounts) {
System.out.println(ftpAccount);
try {
try {
final SftpATTRS attrs = sftp.stat(ftpAccount + File.separator + XXX_DIR);
} catch (Exception e) {
// The folder ftpAccount + File.separator + XXX_DIR does not exist.
// Simply continue...
continue;
}
final Vector<ChannelSftp.LsEntry> files = sftp.ls(ftpAccount + File.separator + "*");
final List<ChannelSftp.LsEntry> ftpFileList = files.stream().collect(Collectors.toList());
for (final ChannelSftp.LsEntry lsEntry : ftpFileList) {
if (lsEntry.getAttrs().isDir() &&
lsEntry.getFilename().equals(XXX_DIR)) {
sftp.ls(ftpAccount + File.separator + lsEntry.getFilename() +
File.separator + "*", new ChannelSftp.LsEntrySelector() {

@Override
public int select (final ChannelSftp.LsEntry entry) {
final Matcher mtc = pattern.matcher(entry.getFilename());
final SftpATTRS attr = entry.getAttrs();
if (mtc.find() && !attr.isDir() && !attr.isLink()) {
System.out.println(entry.getFilename());
try {
final ByteArrayOutputStream baos = new
ByteArrayOutputStream();
sftp.get(ftpAccount + File.separator +
XXX_DIR + File.separator + entry.getFilename(), baos);
vaFiles.put(ftpAccount + File.separator +
XXX_DIR + File.separator + entry.getFilename(),
baos.toByteArray());
logger.info("File " + ftpAccount + File.separator +
XXX_DIR + File.separator + entry.getFilename() + " downloaded.");
baos.close();
} catch (IOException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
}
System.out.println("CONTINUE = " + CONTINUE);
return CONTINUE;
}
});
}//end if
}
} catch (SftpException e) {
e.printStackTrace();
}
break;
}
} catch (JSchException e) {
e.printStackTrace();
}

return vaFiles;
}

这是我打开和关闭 ByteArrayOutputStream 的方式吗?

异常(exception):

4: 
at com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1747)
at de.postcon.SftpFileHandler.readFiles(SftpFileHandler.java:150)
at de.postcon.VaFtp2EmMover.downloadVAFiles(VaFtp2EmMover.java:145)
at de.postcon.VaFtp2EmMover.main(VaFtp2EmMover.java:84)
Caused by: java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at com.jcraft.jsch.Buffer.getByte(Buffer.java:148)
at com.jcraft.jsch.Buffer.getString(Buffer.java:188)
at com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1675)
... 3 more

将方法的代码最小化为:

public Map<String, byte[]> readFiles () {
final Map<String, byte[]> vaFiles = new HashMap();
final String ftpAccount = "/accumio";
try {
sftp.ls(ftpAccount + File.separator + TO_POSTCON_DIR + File.separator + "*", new ChannelSftp.LsEntrySelector() {

@Override
public int select (final ChannelSftp.LsEntry entry) {
final Matcher mtc = pattern.matcher(entry.getFilename());
final SftpATTRS attr = entry.getAttrs();
if (mtc.find() && !attr.isDir() && !attr.isLink()) {
System.out.println(entry.getFilename());
}
System.out.println("CONTINUE = " + CONTINUE);
return CONTINUE;
}
});
} catch (SftpException e) {
e.printStackTrace();
}

return vaFiles;
}

...它正在工作。因此,问题似乎是由 sftp.get(...); 产生的,因为当我放置此行

final ByteArrayOutputStream baos = new ByteArrayOutputStream();
sftp.get(ftpAccount + File.separator + XXX_DIR + File.separator + entry.getFilename(), baos);

在 System.out.println(entry.getFilename()); 之后再次输入,我得到以下 ArrayIndexOutOfBoundsException:

4: 
at com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1747)
at de.postcon.SftpFileHandler.readFiles(SftpFileHandler.java:129)
at de.postcon.VaFtp2EmMover.downloadVAFiles(VaFtp2EmMover.java:145)
at de.postcon.VaFtp2EmMover.main(VaFtp2EmMover.java:84)
Caused by: java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at com.jcraft.jsch.Buffer.getByte(Buffer.java:148)
at com.jcraft.jsch.Buffer.getString(Buffer.java:188)
at com.jcraft.jsch.ChannelSftp.ls(ChannelSftp.java:1675)
... 3 more

解决方案:

public Map<String, byte[]> readFiles () {
final Map<String, byte[]> vaFiles = new HashMap();
final Channel channel;
try {
channel = session.openChannel("sftp");
channel.connect();
final List<String> ftpAccounts = Arrays.stream(this.ftpAccounts).collect(Collectors.toList());
// final List<String> ftpFiles = new ArrayList<>();
for (final String ftpAccount : ftpAccounts) {
// System.out.println(ftpAccount);
try {
try {
final SftpATTRS attrs = sftp.stat(ftpAccount + File.separator + XXX_DIR);
} catch (Exception e) {
// The folder ftpAccount + File.separator + XXX_DIR does not exist.
// Simply continue...
continue;
}
final Vector<ChannelSftp.LsEntry> files = sftp.ls(ftpAccount + File.separator + "*");
final List<ChannelSftp.LsEntry> ftpFileList = files.stream().collect(Collectors.toList());
final List<ChannelSftp.LsEntry> entries = new ArrayList();
for (final ChannelSftp.LsEntry lsEntry : ftpFileList) {
if (lsEntry.getAttrs().isDir() &&
lsEntry.getFilename().equals(XXX_DIR)) {
sftp.ls(ftpAccount + File.separator + lsEntry.getFilename() +
File.separator + "*", new ChannelSftp.LsEntrySelector() {

@Override
public int select (final ChannelSftp.LsEntry entry) {
final Matcher mtc = pattern.matcher(entry.getFilename());
final SftpATTRS attr = entry.getAttrs();
if (mtc.find() && !attr.isDir() && !attr.isLink()) {
// gather the files to be read...
entries.add(entry);
}
return CONTINUE;
}
});
}//end if
}//end for lsEntry

// store the gathered files...
for( final ChannelSftp.LsEntry entry : entries) {
// System.out.println(entry.getFilename());
try {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
sftp.get(ftpAccount + File.separator + XXX_DIR + File.separator +
entry.getFilename(), baos);
vaFiles.put(entry.getFilename(), baos.toByteArray());
logger.info("File " + ftpAccount + File.separator + XXX_DIR + File.separator + entry.getFilename() + " downloaded.");
baos.close();
} catch (IOException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
}//end for
} catch (SftpException e) {
e.printStackTrace();
}
break;
}
} catch (JSchException e) {
e.printStackTrace();
}

return vaFiles;
}

最佳答案

选择器很可能无法回调ChannelSftp

无论如何你都不需要它。

为什么不像处理子文件夹那样处理文件?

final Vector<ChannelSftp.LsEntry> files = sftp.ls(ftpAccount + File.separator + "*");
final List<ChannelSftp.LsEntry> ftpFileList = files.stream().collect(Collectors.toList());
for (final ChannelSftp.LsEntry lsEntry : ftpFileList) {
...
}

关于java - 为什么 JSch ChannelSftp 返回 "Handle closed"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46926066/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com