转载

java中操作SFTP服务器上的文件下载上传(包括创建SFTP服务器上不存在的文件夹)

依赖用的是 jsch 官网是 http://www.jcraft.com/jsch/

直接上源码吧,看注释就知道怎么用了

链接文原: https://tomoya92.github.io/2019/08/14/java-sftp/

import com.jcraft.jsch.*;

import java.io.File;
import java.util.Vector;

/**
 * Created by tomoya at 2019-08-14
 * <p>
 * 在用这个类里的方法之前,请先调一下 instance() 方法,初始化session和channel
 */
public class SFTPUtil {

    private static ChannelSftp channel;
    private static Session session;

    private SFTPUtil() {
    }

    /**
     * 初始化sftp连接,只有调完这个方法,才能用下面的方法
     *
     * @param host              sftp服务器地址
     * @param username          sftp连接用户名
     * @param password          sftp连接密码
     * @param knowHostsFilename 本地的know_hosts文件,一般在 ~/.ssh/know_hosts 这个位置
     * @return
     */
    private static ChannelSftp instance(String host, String username, String password, String knowHostsFilename) {
        if (channel != null) return channel;
        return initChannel(host, username, password, knowHostsFilename);
    }

    private static ChannelSftp initChannel(String host, String username, String password, String knowHostsFilename) {
        try {
            JSch jsch = new JSch();

//      String knowHostsFilename = "/Users/hh/.ssh/known_hosts";
            jsch.setKnownHosts(knowHostsFilename);

            session = jsch.getSession(username, host);
            session.setPassword(password);

            session.connect();

            Channel _channel = session.openChannel("sftp");
            _channel.connect();

            channel = (ChannelSftp) _channel;

            return channel;
        } catch (JSchException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 下载文件
     *
     * @param remoteFile sftp服务器上文件路径
     * @param localFile  下载到本地的文件路径
     */
    public static void downloadFile(String remoteFile, String localFile) {
        try {
            if (channel == null) return;

            String localDirPath = localFile.substring(0, localFile.lastIndexOf("/"));
            File localDirFile = new File(localDirPath);
            if (!localDirFile.exists()) localDirFile.mkdirs();

            channel.get(remoteFile, localFile);
            // OR
//    InputStream in = sftpChannel.get("remote-file");
            channel.exit();
            session.disconnect();
        } catch (SftpException e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传文件
     *
     * @param remoteFile
     * @param localFile
     */
    public static void uploadFile(String remoteFile, String localFile) {
        try {
            if (channel == null) return;

            channel.put(localFile, remoteFile);
            // OR
//    InputStream in = sftpChannel.get("remote-file");
            channel.exit();
            session.disconnect();
        } catch (SftpException e) {
            e.printStackTrace();
        }
    }

    /**
     * 下载sftp上文件夹, 注意,路径后面不要带 /
     *
     * @param remoteDir
     * @param localDir
     */
    public static void downloadDir(String remoteDir, String localDir) { // With subfolders and all files.
        try {
            // Create local folders if absent.
            if (channel == null) return;

            new File(localDir).mkdirs();

            channel.lcd(localDir);

            // Copy remote folders one by one.
            lsFolderCopy(remoteDir, localDir); // Separated because loops itself inside for subfolders.

            channel.exit();
            session.disconnect();
        } catch (SftpException e) {
            e.printStackTrace();
        }
    }


    // download dir or file
    private static void lsFolderCopy(String sourcePath, String destPath) throws SftpException { // List source (remote, sftp) directory and create a local copy of it - method for every single directory.
        Vector<ChannelSftp.LsEntry> list = channel.ls(sourcePath); // List source directory structure.
        for (ChannelSftp.LsEntry oListItem : list) { // Iterate objects in the list to get file/folder names.
            if (!oListItem.getAttrs().isDir()) { // If it is a file (not a directory).
                //        if (!(new File(destPath + "/" + oListItem.getFilename())).exists() || (oListItem.getAttrs().getMTime() > Long.valueOf(new File(destPath + "/" + oListItem.getFilename()).lastModified() / (long) 1000).intValue())) { // Download only if changed later.
                new File(destPath + "/" + oListItem.getFilename());
                channel.get(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Grab file from source ([source filename], [destination filename]).
                //        }
            } else if (!(".".equals(oListItem.getFilename()) || "..".equals(oListItem.getFilename()))) {
                new File(destPath + "/" + oListItem.getFilename()).mkdirs(); // Empty folder copy.
                lsFolderCopy(sourcePath + "/" + oListItem.getFilename(), destPath + "/" + oListItem.getFilename()); // Enter found folder on server to read its contents and create locally.
            }
        }
    }

    /**
     * 上传文件夹,跟下载一样,路径后面不要带 /
     *
     * @param localDir
     * @param remoteDir
     */
    public static void uploadDir(String localDir, String remoteDir) {
        try {
            if (channel == null) return;

            if (!mkdirsRemoteDir(remoteDir)) return;

            putFolderCopy(localDir, remoteDir);
            channel.exit();
            session.disconnect();
        } catch (SftpException e) {
            e.printStackTrace();
        }
    }

    private static boolean mkdirsRemoteDir(String remoteDir) throws SftpException {
        if (remoteDir.substring(0, 1).equals("/")) {
            String[] paths = remoteDir.split("/");
            String remotePath = "";
            for (String path : paths) {
                remotePath += "/" + path;
                SftpATTRS stat = null;
                try {
                    stat = channel.stat(remotePath);
                } catch (SftpException e) {
//          e.printStackTrace();
                }
                if (stat == null) channel.mkdir(remotePath);
            }
            return true;
        } else {
            return false;
        }
    }

    // upload dir
    private static void putFolderCopy(String localDir, String remoteDir) throws SftpException {
        if (channel == null) return;

        File localDirFile = new File(localDir);

        File[] localFiles = localDirFile.listFiles();
        for (File localFile : localFiles) {
            if (localFile.isDirectory()) {
                channel.mkdir(remoteDir + "/" + localFile.getName());
                putFolderCopy(localDir + "/" + localFile.getName(), remoteDir + "/" + localFile.getName());
            } else {
                channel.put(localDir + "/" + localFile.getName(), remoteDir + "/" + localFile.getName());
            }
        }
    }

}

参考

  • https://stackoverflow.com/questions/11968878/using-jsch-is-there-a-way-to-tell-if-a-remote-file-exists-without-doing-an-ls
  • https://stackoverflow.com/questions/11650013/transfer-folder-and-subfolders-using-channelsftp-in-jsch
  • https://stackoverflow.com/questions/14617/how-to-retrieve-a-file-from-a-server-via-sftp

原文链接:

原文  https://tomoya92.github.io/2019/08/14/java-sftp/
正文到此结束
Loading...