SFTP - Yash-777/LearnJava GitHub Wiki

SFTP server in Windows using OpenSSH

Transferring data wireless over local network isn't something new, people have been doing that for a long time. You may be aware of what I'm talking about: an FTP connection. With an FTP client you can connect one device to another to transfer your data over a network.

Example using com.jcraft.jsch.0.1.54 maven

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

public class SFTP_RemoteFileTransfer {
    private static final Log log = LogFactory.getLog(SFTP_RemoteFileTransfer.class);
    
    static String sftpHost, sftpUsername, sftpPassword;
    static int sftpPort;
    
    public static void main(String[] args) throws Exception {
        
        
        String NewFilePath = "C:/Yash/Reports.sql";
        File newFile = new File(NewFilePath);
        InputStream fileContent = new FileInputStream(newFile);
        String newFileName = newFile.getName();
        
        String destinationDir = "C:/Yash/Workplace SVN Branches/NeonDashboard/RemoteFile",
            archivalDir = "C:/Yash/Workplace SVN Branches/NeonDashboard/RemoteFile/BackUP";
        
        copyReportToDestination(fileContent, newFileName, destinationDir, archivalDir);
    }
    
    public static void copyReportToDestination(InputStream fileContent, String fileName, String destinationDir,
            String archivalDir) 
                    throws Exception{
        Session session = null;
        Channel channel = null;
        ChannelSftp channelSftp = null;

        try {
            JSch jsch = new JSch();
            session = jsch.getSession(sftpUsername, sftpHost, sftpPort);
            session.setPassword(sftpPassword);
            
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            channel = session.openChannel("sftp");
            channel.connect();
            channelSftp = (ChannelSftp) channel;
            channelSftp.cd(destinationDir);
            
            // Move old reports to archive location
            if(archivalDir != null)
                moveExistingFilesToArchive(channelSftp, destinationDir, archivalDir);
            
            // copy new report to destination directory
            copyReportsToDestination(channelSftp, fileContent, fileName, destinationDir);
            
            channel.disconnect();
            session.disconnect();
            if (session.isConnected()) {
                session.disconnect();
            }
        } catch (JSchException|SftpException e) {
            throw new Exception("Failed while transfering file and caught Exception!:"+ e);
        }
    }

    public static void moveExistingFilesToArchive(ChannelSftp channelSftp, String sftpWorkingDir, String destinationDir) throws Exception {
        try {
            Vector<ChannelSftp.LsEntry> filesList = channelSftp.ls("*.*");
            log.info("filesList size:" + filesList.size());
            if (!filesList.isEmpty()) {
                for (ChannelSftp.LsEntry entry : filesList) {
                    String filename = entry.getFilename();
                    log.info("Filename::" + filename);
                    String localFile = sftpWorkingDir + "/" + filename;
                    String archivalFilename = filename;
                    String[] parts = null;
                    if (filename.contains(".")) { // filename.matches("\\*.\\*")
                        log.info("File name change");
                        parts = filename.split("\\.");
                        // ArchivalTimestamp to be appended to filename
                        String timeStamp = new SimpleDateFormat("yyyyMMdd_HH_mm_ss").format(new Date());
                        archivalFilename = parts[0] + "_" + timeStamp + "." + parts[1];
                    }
                    String remoteDir = destinationDir + "/" + archivalFilename;
                    log.info("Ready for transfer" + remoteDir + "\n" + localFile);
                    channelSftp.cd(destinationDir);
                    channelSftp.rename(localFile, remoteDir);
                    channelSftp.cd(sftpWorkingDir);
                }
            }
        } catch (SftpException e) {
            throw new Exception("Failed while transfering file and caught SftpException!:"+ e);
        }
    }

    public static void copyReportsToDestination(ChannelSftp channelSftp, InputStream fileContent, String fileName, String destinationDir) throws Exception {
        try {
            channelSftp.cd(destinationDir);
            log.info("Report upload to Remote directory Starts");
            channelSftp.put(fileContent, destinationDir+"/"+fileName);
            fileContent.close();
            log.info("File uploaded successfully - "+ destinationDir);
        } catch(SftpException|IOException e) {
            throw new Exception("Failed while transfering file and caught Exception!:"+ e);
        }
    }
}