簡體   English   中英

使用JSch在Java中進行文件/目錄同步?

[英]File/Directory synchronization in Java using JSch?

是否可以使用JSch在Java中進行文件/目錄同步? 我需要將目錄從遠程Linux機器同步到本地Windows機器。 這可能嗎 ?

-蒂瓦卡

從SCP服務器下載文件的最簡單方法是使用Commons VFS和JSch:

import java.io.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.vfs2.*;

public class CopyRemoteFile {
    public static void copyRemoteFiles(String host, String user, String remotePath, String localPath) throws IOException {
        FileSystemOptions fsOptions = new FileSystemOptions();
        SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(fsOptions, "no");
        SftpFileSystemConfigBuilder.getInstance().setIdentities(fsOptions,
                new File[] { new File(FileUtils.getUserDirectoryPath() + "/.ssh/id_dsa") });
        DefaultFileSystemManager fsManager = (DefaultFileSystemManager) VFS.getManager();
        String uri = "sftp://" + user + "@" + host + "/" + remotePath;

        FileObject fo = fsManager.resolveFile(uri, fsOptions);

        FileObject[] files = fo.getChildren();
        for (FileObject file : files) {
                    // We will be dealing with the files here only
            if (file.getType() == FileType.FILE) {
                FileUtils.copyInputStreamToFile(file.getContent().getInputStream(),
                        new File(localPath + "/" + file.getName().getBaseName()));
            }
            file.close();
        }

        fo.close();

        fsManager.close();
    }
}

這只是我在Wiki中獲得的一個示例,因此沒有任何幻想。 但是請記住,如果要關閉fsManager ,將無法在同一VM中再次打開它。 我在測試此解決方案時遇到了這個問題...

盡管上面的示例未導入任何JSch類,但是無論如何您都需要將其放在類路徑中。

上面的示例使用私鑰向遠程主機進行身份驗證。 您可以通過提供密碼並修改uri來輕松更改它。

如果需要同步文件,則可以比較本地文件系統(或數據庫或任何其他信息源)上的文件和遠程文件的日期:

import java.io.*;
import org.apache.commons.io.*;
import org.apache.commons.vfs2.*;
import org.apache.commons.vfs2.impl.*;
import org.apache.commons.vfs2.provider.sftp.*;

public class CopyRemoteFile {
    public static void copyRemoteFiles(final String host, final String user, final String remotePath, final String localPath)
            throws IOException {
        FileSystemOptions fsOptions = new FileSystemOptions();
        SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(fsOptions, "no");
        SftpFileSystemConfigBuilder.getInstance().setIdentities(fsOptions,
                new File[] { new File(FileUtils.getUserDirectoryPath() + "/.ssh/id_dsa") });
        DefaultFileSystemManager fsManager = (DefaultFileSystemManager) VFS.getManager();
        String uri = "sftp://" + user + "@" + host + "/" + remotePath;

        FileObject fo = fsManager.resolveFile(uri, fsOptions);

        FileObject[] files = fo.getChildren();
        for (FileObject file : files) {
            // We will be dealing with the files here only
            File newFile = new File(localPath + "/" + file.getName().getBaseName());
            if (file.getType() == FileType.FILE && newFile.lastModified() != file.getContent().getLastModifiedTime()) {
                FileUtils.copyInputStreamToFile(file.getContent().getInputStream(), newFile);
                newFile.setLastModified(file.getContent().getLastModifiedTime());
            } 
            file.close();
        }

        fo.close();

        fsManager.close();
    }
}

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

有一個完整的Programm上傳集。 這是同步部分:

 import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Vector; import com.jcraft.jsch.ChannelSftp.LsEntry; import com.jcraft.jsch.SftpException; /* * This is the heart of the whole Program. I hope, the descriptions are precise enought. */ public class Sync{ public String ServerPath; public File LocalFolder; public sFTPclient client; public ArrayList<String> serverContentList; public ArrayList<String> pathList; public Sync(File local, String to, sFTPclient client){ this.LocalFolder = local; this.ServerPath = to; this.client = client; } /* * Executed once. Sets the Server Directory if it exists. * If the local folder doesn't exist on the Server, it creates it. */ public void setServerDirectory() throws SftpException{ try{ client.sftpChannel.cd(ServerPath); }catch(Exception e){ GUI.addToConsole(ServerPath + " don't exist on your server!"); } String serverFolder = ServerPath.substring(ServerPath.lastIndexOf('/')+1, ServerPath.length()); if(!LocalFolder.getName().equals(serverFolder)){ try{ client.sftpChannel.mkdir(LocalFolder.getName()); client.sftpChannel.cd(LocalFolder.getName()); } catch (Exception e){ client.sftpChannel.cd(LocalFolder.getName()); } this.ServerPath = ServerPath + "/" + LocalFolder.getName(); GUI.setNewServerFolder(ServerPath); } serverContentList = new ArrayList<String>(); pathList = new ArrayList<String>(); } //The contentlist contains all Filenames, that should be synchronized public void setToContentList(String ServerFolder) throws SftpException{ @SuppressWarnings("unchecked") Vector<LsEntry> fileList = client.sftpChannel.ls(ServerFolder); int size = fileList.size(); for(int i = 0; i < size; i++){ if(!fileList.get(i).getFilename().startsWith(".")){ serverContentList.add(fileList.get(i).getFilename()); pathList.add(ServerFolder); } } } /* * Deletes the synchronized elements from the Lists */ public void deleteFromLists(String name){ int position = serverContentList.lastIndexOf(name); if(position >= 0){ serverContentList.remove(position); pathList.remove(position); } } /* * Main function for synchronizing. Works recursive for local folders. */ @SuppressWarnings("unchecked") public void synchronize(File localFolder, String ServerDir) throws SftpException, FileNotFoundException{ if(client.sftpChannel.pwd() != ServerDir){ client.sftpChannel.cd(ServerDir); } setToContentList(ServerDir); File[] localList = localFolder.listFiles(); Vector<LsEntry> ServerList = client.sftpChannel.ls(ServerDir); ServerList.remove(0); ServerList.remove(0); /* * Upload missing Files/Folders */ int size = localList.length; for(int i = 0; i < size; i++){ if(localList[i].isDirectory()){ if(checkFolder(localList[i], ServerDir)){ synchronize(localList[i], ServerDir + "/" + localList[i].getName()); deleteFromLists("SubFolder"); }else { newFileMaster(true, localList[i], ServerDir); } } else { checkFile(localList[i], ServerDir); } deleteFromLists(localList[i].getName()); } } /* * Deletes all files on the server, which are not in the local Folder. Deletes also all missing folders */ public void deleteRest() throws SftpException, FileNotFoundException{ int size = serverContentList.size(); for(int i = 0; i < size; i++){ client.sftpChannel.cd(pathList.get(i)); newFileMaster(false, null, serverContentList.get(i)); } } /* * Copy or delete Files/Folders */ public void newFileMaster(boolean copyOrNot, File sourcePath, String destPath) throws FileNotFoundException, SftpException{ FileMaster copy = new FileMaster(copyOrNot, sourcePath, destPath, client.sftpChannel); copy.runMaster(); } /* *Useful to find errors - Prints out the content-List every time you call the method. *If you have Problems, call it before and after every changes of the serverContentList! */ /*public void printServerContent(){ System.out.println("SERVER-Content: " + "\\n"); for(int i = 0; i < serverContentList.size(); i++){ System.out.println(serverContentList.get(i) + " in " + pathList.get(i)); } }*/ /* * Looks ond the server, if the file is there. If not, or the local file has changed, it copies the file on the server. */ public void checkFile(File file, String path) throws SftpException, FileNotFoundException{ client.sftpChannel.cd(path); if(!serverContentList.contains(file.getName())){ newFileMaster(true, file, ServerPath); } else { Long localTimeStamp = file.lastModified(); Long timeStamp = client.sftpChannel.stat(file.getName()).getATime()*1000L; if(localTimeStamp > timeStamp){ newFileMaster(false, null, path + "/" + file.getName()); newFileMaster(true, file, path); } } deleteFromLists(file.getName()); } /* * The same as the checkFile function. But it returns a boolean. (Easier to handle in the synchronized funtion) * Don't check, if the folder has changed (I think this can't be the case) */ public boolean checkFolder(File folder, String path) throws SftpException{ client.sftpChannel.cd(path); if(serverContentList.contains(folder.getName())){ return true; }else { return false; } } } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM