在JSch中使用channelsftp传输文件夹和子文件夹?

时间:2012-07-25 12:44:03

标签: java sftp jsch

我想使用channelsftp传输文件夹和子文件夹。我可以使用channelsftp.put(src,dest)命令成功传输文件,但这对文件夹不起作用(至少我无法使其工作)。那么有人可以解释我如何使用channelsftp传输文件夹和子文件夹?

3 个答案:

答案 0 :(得分:10)

在jsch中使用多级文件夹结构:

  1. 输入;
  2. 列出他们的内容;
  3. 对每个找到的项目做smth;
  4. 重复1,2和& 3如果找到子文件夹。
  5. 在JSCH类中下载dirs方法:

    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.
            }
        }
    }
    

    在JSCH类中删除dirs方法:

    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.");
    }
    

    从外部打电话给这些方法,如:

    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).
    

答案 1 :(得分:4)

上面的代码(由zon)按照我的理解工作下载。我需要上传到远程服务器。我写下面的代码来实现相同的。如果有任何问题请尝试和评论(它忽略以“。”开头的文件。 “)

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);

                    }

                }
            }

         }

答案 2 :(得分:0)

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

&#13;
&#13;
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());
	}

}
&#13;
&#13;
&#13;