我正在使用jsch 0.1.54,我试图通过SFTP访问FTP服务器。这一切都正常工作,我可以步入所需的目录,但当我使用模式执行文件 channel.ls(" *"); 我只能得到第一场比赛,下一场比赛我得到 "处理关闭 "但不是文件名。为什么呢?
更确切地说,当我最终到达所需的目录时,我做了一个
sftp.ls(ftpAccount + File.separator + lsEntry.getFilename() +
File.separator + "*", new ChannelSftp.LsEntrySelector() {...});
也许LsEntrySelectore是" Handle关闭" 的原因!?
以下是该方法的完整代码:
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的方式吗?
例外:
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;
}
答案 0 :(得分:1)
selector
很可能无法回复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) {
...
}