Transfer folder and subfolders using channelsftp in JSch?

后端 未结 3 688
生来不讨喜
生来不讨喜 2020-12-03 09:16

I want to transfer a folder and a subfolder using channelsftp. I can successfully transfer files using channelsftp.put(src,dest) command but this does not work

相关标签:
3条回答
  • 2020-12-03 09:38

    To work with multilevel folder structures in jsch you:

    1. enter them;
    2. list their contents;
    3. do smth with every found item;
    4. repeat 1, 2 & 3 if subfolder is found.

    DOWNLOAD dirs method inside your JSCH class:

    public void downloadDir(String sourcePath, String destPath) throws SftpException { // With subfolders and all files.
        // Create local folders if absent.
        try {
            new File(destPath).mkdirs();
        } catch (Exception e) {
            System.out.println("Error at : " + destPath);
        }
        sftpChannel.lcd(destPath);
    
        // Copy remote folders one by one.
        lsFolderCopy(sourcePath, destPath); // Separated because loops itself inside for subfolders.
    }
    
    private 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 = sftpChannel.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());
                    sftpChannel.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.
            }
        }
    }
    

    REMOVE dirs method inside your JSCH class:

    try {
        sftpChannel.cd(dir);
        Vector<ChannelSftp.LsEntry> list = sftpChannel.ls(dir); // 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).
                sftpChannel.rm(dir + "/" + oListItem.getFilename()); // Remove file.
            } else if (!".".equals(oListItem.getFilename())) { // If it is a subdir.
                try {
                    sftpChannel.rmdir(dir + "/" + oListItem.getFilename());  // Try removing subdir.
                } catch (Exception e) { // If subdir is not empty and error occurs.
                    lsFolderRemove(dir + "/" + oListItem.getFilename()); // Do lsFolderRemove on this subdir to enter it and clear its contents.
                }
            }
        }
        sftpChannel.rmdir(dir); // Finally remove the required dir.
    } catch (SftpException sftpException) {
        System.out.println("Removing " + dir + " failed. It may be already deleted.");
    }
    

    CALL these methods from outside like:

    MyJSCHClass sftp = new MyJSCHClass();
    sftp.removeDir("/mypublic/myfolders");
    sftp.disconnect(); // Disconnecting is obligatory - otherwise changes on server can be discarded (e.g. loaded folder disappears).
    
    0 讨论(0)
  • 2020-12-03 09:58

    From: http://the-project.net16.net/Projekte/projekte/Projekte/Programmieren/sftp-synchronisierung.html

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.util.Vector;
    import com.jcraft.jsch.ChannelSftp;
    import com.jcraft.jsch.ChannelSftp.LsEntry;
    import com.jcraft.jsch.SftpException;
    
    public class FileMaster {
    	public boolean FileAction;
    	public File local;
    	public String serverDir;
    	public ChannelSftp channel;
    	
    	public FileMaster(boolean copyOrDelete, File local, String to, ChannelSftp channel){
    		this.FileAction = copyOrDelete;
    		this.local = local;
    		this.serverDir = to;
    		this.channel = channel;
    	}
    	
    	/*
    	 * If FileAction = true, the File local is copied to the serverDir, else the file is deleted.
    	 */
    	public void runMaster() throws FileNotFoundException, SftpException{
    		if(FileAction){
    			copy(local, serverDir, channel);
    		} else { 
    			delete(serverDir, channel);
    		}
    	}
    	
    	/*
    	 * Copies recursive
    	 */
    	public static void copy(File localFile, String destPath, ChannelSftp clientChannel) throws SftpException, FileNotFoundException{
    		if(localFile.isDirectory()){
    			clientChannel.mkdir(localFile.getName());
    			GUI.addToConsole("Created Folder: " + localFile.getName() + " in " + destPath);
    
    			destPath = destPath + "/" + localFile.getName();
    			clientChannel.cd(destPath);
    			
    			for(File file: localFile.listFiles()){
    				copy(file, destPath, clientChannel);
    			}
    			clientChannel.cd(destPath.substring(0, destPath.lastIndexOf('/')));
    		} else {
    			GUI.addToConsole("Copying File: " + localFile.getName() + " to " + destPath);
    			clientChannel.put(new FileInputStream(localFile), localFile.getName(),ChannelSftp.OVERWRITE);
    		}
    
    	}
    	
    	/*
    	 * File/Folder is deleted, but not recursive
    	 */
    	public void delete(String filename, ChannelSftp sFTPchannel) throws SftpException{		
    		if(sFTPchannel.stat(filename).isDir()){
    			@SuppressWarnings("unchecked")
    			Vector<LsEntry> fileList = sFTPchannel.ls(filename);
    			sFTPchannel.cd(filename);
    			int size = fileList.size();
    			for(int i = 0; i < size; i++){
    				if(!fileList.get(i).getFilename().startsWith(".")){
    					delete(fileList.get(i).getFilename(), sFTPchannel);
    				}
    			}
    			sFTPchannel.cd("..");
    			sFTPchannel.rmdir(filename);
    		} else {
    			sFTPchannel.rm(filename.toString());
    		}
    		GUI.addToConsole("Deleted: " + filename + " in " + sFTPchannel.pwd());
    	}
    
    }

    0 讨论(0)
  • 2020-12-03 10:01

    Above code(by zon) works for download as per my understanding.I need to upload to a remote server.I wrote below code to achieve the same.Please try and comment if any issue(it ignores files starting with ".")

    private static void lsFolderCopy(String sourcePath, String destPath,
                ChannelSftp sftpChannel) throws SftpException,   FileNotFoundException {
        File localFile = new File(sourcePath);
    
    if(localFile.isFile())
    {
    
        //copy if it is a file
        sftpChannel.cd(destPath);
    
        if(!localFile.getName().startsWith("."))
        sftpChannel.put(new FileInputStream(localFile), localFile.getName(),ChannelSftp.OVERWRITE);
    }   
    else{
        System.out.println("inside else "+localFile.getName());
        File[] files = localFile.listFiles();
    
        if(files!=null && files.length > 0 && !localFile.getName().startsWith("."))
        {
    
            sftpChannel.cd(destPath);
            SftpATTRS  attrs = null;
    
        //check if the directory is already existing
        try {
            attrs = sftpChannel.stat(destPath+"/"+localFile.getName());
        } catch (Exception e) {
            System.out.println(destPath+"/"+localFile.getName()+" not found");
        }
    
        //else create a directory   
        if (attrs != null) {
            System.out.println("Directory exists IsDir="+attrs.isDir());
        } else {
            System.out.println("Creating dir "+localFile.getName());
            sftpChannel.mkdir(localFile.getName());
        }
    
        //System.out.println("length " + files.length);
    
         for(int i =0;i<files.length;i++) 
            {
    
             lsFolderCopy(files[i].getAbsolutePath(),destPath+"/"+localFile.getName(),sftpChannel);
    
                        }
    
                    }
                }
    
             }
    
    0 讨论(0)
提交回复
热议问题