public class SftpClient {
private final JSch jSch;
private Session session;
private ChannelSftp channelSftp;
private boolean connected;
public SftpClient() { this.jSch = new JSch(); }
public void connect(final ConnectionDetails details) throws ConnectionException {
try {
if (details.usesDefaultPort()) {
session = jSch.getSession(details.getUserName(), details.getHost());
} else {
session = jSch.getSession(details.getUserName(), details.getHost(), details.getPort());
}
channelSftp = createSftp(session, details.getPassword());
channelSftp.connect();
connected = session.isConnected();
} catch (JSchException e) {
throw new ConnectionException(e.getMessage());
}
}
public void disconnect() {
if (connected) {
channelSftp.disconnect();
session.disconnect();
}
}
public void cd(final String path) throws FileActionException {
try {
channelSftp.cd(path);
} catch (SftpException e) {
throw new FileActionException(e.getMessage());
}
}
public List<FileWrapper> list() throws FileActionException {
try {
return collectToWrapperList(channelSftp.ls("*"));
} catch (SftpException e) {
throw new FileActionException(e.getMessage());
}
}
public String pwd() throws FileActionException {
try {
return channelSftp.pwd();
} catch (SftpException e) {
throw new FileActionException(e.getMessage());
}
}
public boolean rename(final FileWrapper wrapper, final String newFileName) throws FileActionException {
try {
String currentPath = channelSftp.pwd();
channelSftp.rename(currentPath + wrapper.getFileName(), currentPath + newFileName);
} catch (SftpException e) {
throw new FileActionException(e.getMessage());
}
return true;
}
private List<FileWrapper> collectToWrapperList(Vector<ChannelSftp.LsEntry> entries) {
return entries.stream()
.filter(entry -> !entry.getAttrs().isDir())
.map(entry -> FileWrapper.from(entry.getAttrs().getMtimeString(), entry.getFilename(), entry.getAttrs().getSize()))
.collect(Collectors.toList());
}
private ChannelSftp createSftp(final Session session, final String password) throws JSchException {
session.setPassword(password);
Properties properties = new Properties();
properties.setProperty("StrictHostKeyChecking", "no");
session.setConfig(properties);
session.connect();
return (ChannelSftp) session.openChannel("sftp");
}
}
Обратите внимание, что метод list
эффективно возвращает список FileWrapper
объектов вместо LsEntry
объектов.
public class FileWrapper {
private static final String TIME_FORMAT = "EEE MMM dd HH:mm:ss zzz yyyy";
private Date timeStamp;
public Date getTimeStamp() { return timeStamp; }
private String fileName;
public String getFileName() { return fileName; }
private Long fileSize;
public Long getFileSize() { return fileSize; }
private FileWrapper(String timeStamp, String fileName, Long fileSize) throws ParseException {
this.timeStamp = new SimpleDateFormat(TIME_FORMAT).parse(timeStamp);
this.fileName = fileName;
this.fileSize = fileSize;
}
public static FileWrapper from(final String timeStamp, final String fileName, final Long fileSize) {
try {
return new FileWrapper(timeStamp, fileName, fileSize);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
С этим вы можете легко составить список удаленного каталога и получить все атрибуты файлов.
Имея это под рукой, вы можете просто вызвать SftpClient#rename
и переименовать нужный файл.
Я знаю, что вы хотите избежать рефакторинга, но, учитывая очень жесткий характер или LsEntry
, а также тот факт, что библиотека все еще использует Vector
и так далее, я полагаю, что это лучший путь (вы буду избегать головных болей в будущем).
Я знаю, что это может быть не на 100% ответ, который вы ожидаете, но я думаю, что это будет полезно для вас.