2012-07-25 85 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 } 
 

 
}

相關問題