jsch通过SFTP查找特定文件

问题描述 投票:-1回答:1

我有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.             
java sftp jsch
1个回答
1
投票
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%答案,但我认为它会对你有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.