我有Java应用程序通过SFTP连接到Linux。我正在使用jsch作为框架。现在,假设我需要重命名文件。
public boolean rename(String name) {
boolean result = false;
channelSftp = (ChannelSftp)channel;
LsEntry currentFile = //here I have LsEntry object, pointing to specific record;
logger.info("Renaming CRC file " + currentFile.getFilename() + " to " + name);
try {
//For the first parameter I get current position in the directory, then I append the filename of the currently processed file.
//For the first parameter I get current position in the directory, then I append the new name.
channel.rename(channel.pwd() + currentFile .getFilename(), channel.pwd() + name);
result = true;
} catch (Exception e) {
logger.error("Error renaming crc file to " + name, e);
result = false;
}
return result;
}
现在重命名文件系统上的文件后,我还需要在我正在使用的当前LsEntry对象中重命名该文件。问题是LsEntry没有提供这样的方法,所以我必须再次加载它。现在我该怎么找?我需要找到特定的文件,以便我可以将其用作更新的LsEntry对象供以后使用。那可能吗?
EDIT1
LsEntry对象,表示文件系统上的条目必须以某种方式创建,我通过将矢量对象转换为它来做到这一点。像这样:
System.out.println("searching for files in following directory" + directory);
channelSftp.cd(directory);
Vector foundFiles = channelSftp.ls(directory);
for(int i=2; i<foundFiles.size();i++){
LsEntry files = (LsEntry) foundFiles.get(i);
System.out.println("found file: " + files.getFilename());
System.out.println("Found file with details : " + files.getLongname());
System.out.println("Found file on path: " + channelSftp.pwd());
channelSftp.rename(channelSftp.pwd() + files.getFilename(), channelSftp.pwd() + "picovina");
//LsEntry has now old name.
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%答案,但我认为它会对你有所帮助。