2012-07-25 184 views
2

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

+1

您可以尝试压缩和解文件夹和转移它作为一个文件,并在目的地解压它。这是大多数FTP程序无论如何做的。 – roymustang86 2012-07-25 12:54:53

+1

好吧,这是一种解决方案,但没有办法复制文件夹及其所有内容,而无需使用sftp进行压缩? – waqas 2012-07-25 12:59:14

+0

显然顾名思义,它是一个'文件'传输协议 – roymustang86 2012-07-25 13:02:15

回答

10

要使用多级文件夹结构jsch你工作:

  1. 进入他们。
  2. 列出其内容;
  3. 对每个找到的物品都做不到;
  4. 重复1,2 & 3如果找到子文件夹。

下载迪尔斯你JSCH类中的方法:

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迪尔斯方法您JSCH类中:

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

在lsFolderCopyMethod中,我还必须添加fileName为“..”的情况:'!( “。”。equals(oListItem.getFilename())||“..”。equals(oListItem.getFilename()))'让它工作。 – 2014-03-13 12:24:41

+0

谢谢,更新。看来我也已经意识到这一点,但忘了在这里更新案例。 – Zon 2014-03-15 18:12:11

+0

该编辑中的小错字,缺少一个括号。我没有编辑权限... '} else if(!(“。”。equals(oListItem.getFilename())||“..”。equals(oListItem.getFilename())){' – gdbj 2017-05-19 16:26:43

4

以上代码(由zon)根据我的unde进行下载rstanding.I需要上传到远程server.I写了下面的代码来实现same.Please尝试和评论,如果任何问题

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

JSCH用于远程连接。要使用本地文件系统,您还需要使用java.io.File类。但是你可以尝试连接你的本地主机,就好像它是一个远程主机一样。 – Zon 2015-09-29 14:09:16

+0

Zon ..我发布的这段代码是上传到远程系统...(这段代码是用来从开发者盒子上传一个ear文件到服务器盒 - 自动使用jenkins的。) – 2015-11-05 04:31:39

+0

这是优秀的代码和工作正常。但是如果我想复制以点(。)开头的文件,那该怎么办?在评论该行后,仍然没有复制相同的内容? – Aditya 2017-04-30 07:29:35

0

从(它忽略开头的文件“”):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 { 
 
\t public boolean FileAction; 
 
\t public File local; 
 
\t public String serverDir; 
 
\t public ChannelSftp channel; 
 
\t 
 
\t public FileMaster(boolean copyOrDelete, File local, String to, ChannelSftp channel){ 
 
\t \t this.FileAction = copyOrDelete; 
 
\t \t this.local = local; 
 
\t \t this.serverDir = to; 
 
\t \t this.channel = channel; 
 
\t } 
 
\t 
 
\t /* 
 
\t * If FileAction = true, the File local is copied to the serverDir, else the file is deleted. 
 
\t */ 
 
\t public void runMaster() throws FileNotFoundException, SftpException{ 
 
\t \t if(FileAction){ 
 
\t \t \t copy(local, serverDir, channel); 
 
\t \t } else { 
 
\t \t \t delete(serverDir, channel); 
 
\t \t } 
 
\t } 
 
\t 
 
\t /* 
 
\t * Copies recursive 
 
\t */ 
 
\t public static void copy(File localFile, String destPath, ChannelSftp clientChannel) throws SftpException, FileNotFoundException{ 
 
\t \t if(localFile.isDirectory()){ 
 
\t \t \t clientChannel.mkdir(localFile.getName()); 
 
\t \t \t GUI.addToConsole("Created Folder: " + localFile.getName() + " in " + destPath); 
 

 
\t \t \t destPath = destPath + "/" + localFile.getName(); 
 
\t \t \t clientChannel.cd(destPath); 
 
\t \t \t 
 
\t \t \t for(File file: localFile.listFiles()){ 
 
\t \t \t \t copy(file, destPath, clientChannel); 
 
\t \t \t } 
 
\t \t \t clientChannel.cd(destPath.substring(0, destPath.lastIndexOf('/'))); 
 
\t \t } else { 
 
\t \t \t GUI.addToConsole("Copying File: " + localFile.getName() + " to " + destPath); 
 
\t \t \t clientChannel.put(new FileInputStream(localFile), localFile.getName(),ChannelSftp.OVERWRITE); 
 
\t \t } 
 

 
\t } 
 
\t 
 
\t /* 
 
\t * File/Folder is deleted, but not recursive 
 
\t */ 
 
\t public void delete(String filename, ChannelSftp sFTPchannel) throws SftpException{ \t \t 
 
\t \t if(sFTPchannel.stat(filename).isDir()){ 
 
\t \t \t @SuppressWarnings("unchecked") 
 
\t \t \t Vector<LsEntry> fileList = sFTPchannel.ls(filename); 
 
\t \t \t sFTPchannel.cd(filename); 
 
\t \t \t int size = fileList.size(); 
 
\t \t \t for(int i = 0; i < size; i++){ 
 
\t \t \t \t if(!fileList.get(i).getFilename().startsWith(".")){ 
 
\t \t \t \t \t delete(fileList.get(i).getFilename(), sFTPchannel); 
 
\t \t \t \t } 
 
\t \t \t } 
 
\t \t \t sFTPchannel.cd(".."); 
 
\t \t \t sFTPchannel.rmdir(filename); 
 
\t \t } else { 
 
\t \t \t sFTPchannel.rm(filename.toString()); 
 
\t \t } 
 
\t \t GUI.addToConsole("Deleted: " + filename + " in " + sFTPchannel.pwd()); 
 
\t } 
 

 
}

相关问题