回答
從SCP服務器下載文件最簡單的方法是用JSch一起使用Commons VFS:
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
,則無法在同一個虛擬機中再次打開它。我在測試這個解決方案時遇到了這個問題...
儘管上面的例子沒有導入任何JSch類,但是您仍然需要將它放在classpath中。
上述示例使用私鑰對遠程主機進行身份驗證。您可以通過提供密碼並修改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();
}
}
感謝Lukasz的代碼。完全正確,同步「我想從遠程主機下載所有新的和修改的文件,並從本地目錄上傳新的和修改的文件」。下面的代碼將所有文件從遠程複製到本地,即使該文件未被修改。我不想下載未修改的文件。我該如何實現這個目標? – Tivakar 2012-02-15 21:49:03
請 - 請閱讀API。它在那裏。 'File.getContent()。getLastModifiedTime()'會給你所需要的信息。因此,比較這兩者可以爲您提供文件是否被修改的信息。你可以用本地文件,數據庫的某個源或者存儲......來檢查它。只需路徑,名稱和最後修改時間即可。 – 2012-02-15 22:34:27
感謝盧卡斯。真的很有幫助 – Tivakar 2012-02-16 04:49:38
看:
如果需要同步文件,你可以在本地文件系統(或DB,或信息的任何其他來源)和遠程文件上比較文件的日期在:http://the-project.net16.net/Projekte/projekte/Projekte/Programmieren/sftp-synchronisierung.html
有一個完整的Programm uploadet。 這裏是同步部分:
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{
\t public String ServerPath;
\t public File LocalFolder;
\t public sFTPclient client;
\t public ArrayList<String> serverContentList;
\t public ArrayList<String> pathList;
\t \t
\t public Sync(File local, String to, sFTPclient client){
\t \t this.LocalFolder = local;
\t \t this.ServerPath = to;
\t \t this.client = client;
\t }
\t
\t /*
\t * Executed once. Sets the Server Directory if it exists.
\t * If the local folder doesn't exist on the Server, it creates it.
\t */
\t public void setServerDirectory() throws SftpException{
\t \t try{
\t \t \t client.sftpChannel.cd(ServerPath);
\t \t }catch(Exception e){
\t \t \t GUI.addToConsole(ServerPath + " don't exist on your server!");
\t \t }
\t \t
\t \t String serverFolder = ServerPath.substring(ServerPath.lastIndexOf('/')+1, ServerPath.length());
\t \t if(!LocalFolder.getName().equals(serverFolder)){
\t \t \t try{
\t \t \t \t client.sftpChannel.mkdir(LocalFolder.getName());
\t \t \t \t client.sftpChannel.cd(LocalFolder.getName());
\t \t \t } catch (Exception e){
\t \t \t \t client.sftpChannel.cd(LocalFolder.getName());
\t \t \t }
\t \t \t this.ServerPath = ServerPath + "/" + LocalFolder.getName();
\t \t \t GUI.setNewServerFolder(ServerPath);
\t \t }
\t \t serverContentList = new ArrayList<String>();
\t \t pathList = new ArrayList<String>();
\t \t
\t }
\t
\t //The contentlist contains all Filenames, that should be synchronized
\t public void setToContentList(String ServerFolder) throws SftpException{
\t \t @SuppressWarnings("unchecked")
\t \t Vector<LsEntry> fileList = client.sftpChannel.ls(ServerFolder);
\t \t int size = fileList.size();
\t \t for(int i = 0; i < size; i++){
\t \t \t if(!fileList.get(i).getFilename().startsWith(".")){
\t \t \t \t serverContentList.add(fileList.get(i).getFilename());
\t \t \t \t pathList.add(ServerFolder);
\t \t \t }
\t \t }
\t }
\t
\t /*
\t * Deletes the synchronized elements from the Lists
\t */
\t public void deleteFromLists(String name){
\t \t int \t position = serverContentList.lastIndexOf(name);
\t \t \t \t
\t \t if(position >= 0){ \t
\t \t \t serverContentList.remove(position);
\t \t \t pathList.remove(position);
\t \t }
\t }
\t
\t /*
\t * Main function for synchronizing. Works recursive for local folders.
\t */
\t @SuppressWarnings("unchecked")
\t public void synchronize(File localFolder, String ServerDir) throws SftpException, FileNotFoundException{
\t \t if(client.sftpChannel.pwd() != ServerDir){
\t \t \t client.sftpChannel.cd(ServerDir);
\t \t }
\t \t setToContentList(ServerDir);
\t \t
\t \t File[] localList = localFolder.listFiles();
\t \t Vector<LsEntry> ServerList = client.sftpChannel.ls(ServerDir);
\t \t ServerList.remove(0); ServerList.remove(0);
\t \t
\t \t /*
\t \t * Upload missing Files/Folders
\t \t */
\t \t int size = localList.length;
\t \t for(int i = 0; i < size; i++){
\t \t \t if(localList[i].isDirectory()){
\t \t \t \t if(checkFolder(localList[i], ServerDir)){
\t \t \t \t \t synchronize(localList[i], ServerDir + "/" + localList[i].getName());
\t \t \t \t \t deleteFromLists("SubFolder");
\t \t \t \t }else {
\t \t \t \t \t newFileMaster(true, localList[i], ServerDir);
\t \t \t \t }
\t \t \t } else {
\t \t \t \t checkFile(localList[i], ServerDir);
\t \t \t }
\t \t \t deleteFromLists(localList[i].getName());
\t \t }
\t }
\t
\t /*
\t * Deletes all files on the server, which are not in the local Folder. Deletes also all missing folders
\t */
\t public void deleteRest() throws SftpException, FileNotFoundException{
\t \t int size = serverContentList.size();
\t \t for(int i = 0; i < size; i++){
\t \t \t client.sftpChannel.cd(pathList.get(i));
\t \t \t newFileMaster(false, null, serverContentList.get(i));
\t \t }
\t }
\t
\t /*
\t * Copy or delete Files/Folders
\t */
\t public void newFileMaster(boolean copyOrNot, File sourcePath, String destPath) throws FileNotFoundException, SftpException{
\t \t FileMaster copy = new FileMaster(copyOrNot, sourcePath, destPath, client.sftpChannel);
\t \t copy.runMaster();
\t }
\t
\t /*
\t *Useful to find errors - Prints out the content-List every time you call the method.
\t *If you have Problems, call it before and after every changes of the serverContentList!
\t */
\t /*public void printServerContent(){
\t \t System.out.println("SERVER-Content: " + "\n");
\t \t for(int i = 0; i < serverContentList.size(); i++){
\t \t \t System.out.println(serverContentList.get(i) + " in " + pathList.get(i));
\t \t }
\t }*/
\t
\t /*
\t * Looks ond the server, if the file is there. If not, or the local file has changed, it copies the file on the server.
\t */
\t public void checkFile(File file, String path) throws SftpException, FileNotFoundException{
\t \t client.sftpChannel.cd(path);
\t \t
\t \t if(!serverContentList.contains(file.getName())){
\t \t \t newFileMaster(true, file, ServerPath);
\t \t } else {
\t \t \t Long localTimeStamp = file.lastModified();
\t \t \t Long timeStamp = client.sftpChannel.stat(file.getName()).getATime()*1000L;
\t \t \t if(localTimeStamp > timeStamp){
\t \t \t \t newFileMaster(false, null, path + "/" + file.getName());
\t \t \t \t newFileMaster(true, file, path);
\t \t \t }
\t \t }
\t \t deleteFromLists(file.getName());
\t }
\t
\t /*
\t * The same as the checkFile function. But it returns a boolean. (Easier to handle in the synchronized funtion)
\t * Don't check, if the folder has changed (I think this can't be the case)
\t */
\t public boolean checkFolder(File folder, String path) throws SftpException{
\t \t client.sftpChannel.cd(path);
\t \t if(serverContentList.contains(folder.getName())){
\t \t \t return true;
\t \t }else { return false; }
\t }
\t
}
- 1. 使用db值進行Java同步
- 2. 使用Gradle同步目錄
- 3. SCP使用JSCH的二進制文件
- 4. 使用Java的SFTP文件傳輸JSch
- 5. 如何同步目錄b中的目錄a中的文件?
- 6. 使用AsynchAppender在Java EE中進行異步記錄
- 7. 在Java中使用方法進行同步?
- 8. 使用SymmetricDS進行條件同步
- 9. 使用svnkit進行同步
- 10. 文件/目錄同步算法
- 11. 跨網絡的文件/目錄同步
- 12. 在不同的目錄中使用Java的exec運行.sh文件?
- 13. 使用JSCH設置目錄權限CHMOD
- 14. 在Java中使用JSch在服務器上創建嵌套目錄
- 15. 如何使用Java JSch庫逐行讀取遠程文件?
- 16. 使用rsync從多個目錄同步txt文件
- 17. 異口同聲地同步在目錄中的文件,但沒有文件夾
- 18. 如何使用java同步文件操作?同步或鎖定?
- 19. jsch和從特定目錄運行sudo
- 20. 遠程進行文件系統同步
- 21. 在Java JSch程序中使用'become'命令來訪問受限目錄
- 22. Jsch rm線程在Android上同步
- 23. 在同步內進行異步調用
- 24. 如何使用java在OpenLdap和Active Directory之間進行同步?
- 25. 排除在嵌套目錄中的特定文件使用ansible同步模塊
- 26. 使用JSch將文件放到遠程目錄中,如果該目錄不存在,則創建它
- 27. 尋找目錄同步的java庫
- 28. 如何使用的iCloud進行同步駐留在文件夾中的應用
- 29. 與使用java的linux服務器進行交互JSCH
- 30. 的Java - 運行JAR拒絕加載文件在同一目錄
你能更詳細解釋這項任務?同步programaticaly或您只是尋找一個應用程序的解決方案?同步是什麼意思? – 2012-02-14 20:15:35
同步是同步。我想以編程方式做。我在我的linux機器上有一個目錄,我想下載/同步目錄中的文件到本地的Windows機器上。我想以編程方式執行此操作,因爲我有一個名爲「sync」的按鈕,應該啓動此過程。 – Tivakar 2012-02-14 20:43:41
對於我來說_sync_意味着我想從遠程主機下載所有新的和修改的文件,並從本地目錄上傳新的和修改的文件。但那是我。無論如何 - 你有你的答案:) – 2012-02-14 22:06:01