Jaka jest najlepsza metoda wykonania transferu scp za pomocą języka programowania Java? Wygląda na to, że mogę to zrobić za pomocą JSSE, JSch lub bibliotek Java Bouncy Castle. Żadne z tych rozwiązań nie wydaje się mieć łatwej odpowiedzi.
81
Odpowiedzi:
Skończyło się na tym, że korzystałem z Jsch - było to całkiem proste i wydawało się, że skalowałem się całkiem nieźle ( łapałem kilka tysięcy plików co kilka minut).
źródło
wtyczka: sshj to jedyny rozsądny wybór! Aby rozpocząć, zobacz poniższe przykłady: pobieranie , przesyłanie .
źródło
Spójrz tutaj
To jest kod źródłowy zadania SCP Antsa. Kod w metodzie „wykonaj” to miejsce, w którym znajdują się jej nakrętki i śruby. To powinno dać ci rzetelny obraz tego, co jest wymagane. Wydaje mi się, że używa JSch.
Alternatywnie możesz również wykonać to zadanie Ant bezpośrednio z kodu Java.
źródło
Opakowałem Jsch kilkoma narzędziami, aby uczynić go nieco bardziej przyjaznym i nazwałem go
Jscp
Dostępne tutaj: https://github.com/willwarren/jscp
Narzędzie SCP do tarowania folderu, spakowania go i scpowania gdzieś, a następnie rozpakowania.
Stosowanie:
// create secure context SecureContext context = new SecureContext("userName", "localhost"); // set optional security configurations. context.setTrustAllHosts(true); context.setPrivateKeyFile(new File("private/key")); // Console requires JDK 1.7 // System.out.println("enter password:"); // context.setPassword(System.console().readPassword()); Jscp.exec(context, "src/dir", "destination/path", // regex ignore list Arrays.asList("logs/log[0-9]*.txt", "backups") );
Zawiera również przydatne klasy - Scp i Exec oraz TarAndGzip, które działają w podobny sposób.
źródło
Jest to rozwiązanie wysokopoziomowe , nie trzeba odkrywać na nowo. Szybko i brudno!
1) Najpierw przejdź do http://ant.apache.org/bindownload.cgi i pobierz najnowszy plik binarny Apache Ant. (obecnie apache-ant-1.9.4-bin.zip).
2) Wypakuj pobrany plik i znajdź JAR ant-jsch.jar („apache-ant-1.9.4 / lib / ant-jsch.jar”). Dodaj ten plik JAR do swojego projektu . Również ant-launcher.jar i ant.jar.
3) Idź do Jcraft jsch SouceForge Project i pobierz jar. Obecnie jsch-0.1.52.jar . Dodaj również ten plik JAR do swojego projektu .
Teraz możesz łatwo użyć w kodzie java Ant Classes Scp do kopiowania plików przez sieć lub SSHExec do poleceń na serwerach SSH.
4) Przykładowy kod Scp:
// This make scp copy of // one local file to remote dir org.apache.tools.ant.taskdefs.optional.ssh.Scp scp = new Scp(); int portSSH = 22; String srvrSSH = "ssh.your.domain"; String userSSH = "anyuser"; String pswdSSH = new String ( jPasswordField1.getPassword() ); String localFile = "C:\\localfile.txt"; String remoteDir = "/uploads/"; scp.setPort( portSSH ); scp.setLocalFile( localFile ); scp.setTodir( userSSH + ":" + pswdSSH + "@" + srvrSSH + ":" + remoteDir ); scp.setProject( new Project() ); scp.setTrust( true ); scp.execute();
źródło
Projekt openssh wymienia kilka alternatyw Javy, Trilead SSH dla Javy wydaje się pasować do tego, o co prosisz.
źródło
Używam tego SFTP API, które ma SCP o nazwie Zehon, jest świetne, tak łatwe w użyciu z dużą ilością przykładowego kodu. Oto witryna http://www.zehon.com
źródło
Spojrzałem na wiele z tych rozwiązań i wielu z nich nie lubiłem. Głównie dlatego, że irytujący krok polegający na konieczności identyfikacji znanych hostów. To i JSCH jest na absurdalnie niskim poziomie w stosunku do polecenia scp.
Znalazłem bibliotekę, która tego nie wymaga, ale jest spakowana i używana jako narzędzie wiersza poleceń. https://code.google.com/p/scp-java-client/
Przejrzałem kod źródłowy i odkryłem, jak go używać bez wiersza poleceń. Oto przykład przesyłania:
uk.co.marcoratto.scp.SCP scp = new uk.co.marcoratto.scp.SCP(new uk.co.marcoratto.scp.listeners.SCPListenerPrintStream()); scp.setUsername("root"); scp.setPassword("blah"); scp.setTrust(true); scp.setFromUri(file.getAbsolutePath()); scp.setToUri("root@host:/path/on/remote"); scp.execute();
Największym minusem jest to, że nie ma go w repozytorium Maven (które mogłem znaleźć). Ale łatwość użycia jest dla mnie tego warta.
źródło
jsCH świetnie się dla mnie sprawdził. Poniżej znajduje się przykład metody, która połączy się z serwerem sftp i pobierze pliki do określonego katalogu. Zaleca się trzymanie się z daleka od wyłączania StrictHostKeyChecking. Chociaż konfiguracja jest nieco trudniejsza, ze względów bezpieczeństwa normą powinno być określenie znanych hostów.
jsch.setKnownHosts ("C: \ Users \ test \ known_hosts"); Zalecana
JSch.setConfig ("StrictHostKeyChecking", "nie"); - Niepolecane
import com.jcraft.jsch.*; public void downloadFtp(String userName, String password, String host, int port, String path) { Session session = null; Channel channel = null; try { JSch ssh = new JSch(); JSch.setConfig("StrictHostKeyChecking", "no"); session = ssh.getSession(userName, host, port); session.setPassword(password); session.connect(); channel = session.openChannel("sftp"); channel.connect(); ChannelSftp sftp = (ChannelSftp) channel; sftp.get(path, "specify path to where you want the files to be output"); } catch (JSchException e) { System.out.println(userName); e.printStackTrace(); } catch (SftpException e) { System.out.println(userName); e.printStackTrace(); } finally { if (channel != null) { channel.disconnect(); } if (session != null) { session.disconnect(); } } }
źródło
Tak jak niektórzy tutaj, napisałem otokę wokół biblioteki JSch.
Nazywa się way-secshell i jest hostowany na GitHub:
https://github.com/objectos/way-secshell
// scp myfile.txt localhost:/tmp File file = new File("myfile.txt"); Scp res = WaySSH.scp() .file(file) .toHost("localhost") .at("/tmp") .send();
źródło
JSch to przyjemna biblioteka do pracy. Ma dość prostą odpowiedź na twoje pytanie.
JSch jsch=new JSch(); Session session=jsch.getSession(user, host, 22); session.setPassword("password"); Properties config = new Properties(); config.put("StrictHostKeyChecking","no"); session.setConfig(config); session.connect(); boolean ptimestamp = true; // exec 'scp -t rfile' remotely String command="scp " + (ptimestamp ? "-p" :"") +" -t "+rfile; Channel channel=session.openChannel("exec"); ((ChannelExec)channel).setCommand(command); // get I/O streams for remote scp OutputStream out=channel.getOutputStream(); InputStream in=channel.getInputStream(); channel.connect(); if(checkAck(in)!=0){ System.exit(0); } File _lfile = new File(lfile); if(ptimestamp){ command="T "+(_lfile.lastModified()/1000)+" 0"; // The access time should be sent here, // but it is not accessible with JavaAPI ;-< command+=(" "+(_lfile.lastModified()/1000)+" 0\n"); out.write(command.getBytes()); out.flush(); if(checkAck(in)!=0){ System.exit(0); } }
Pełny kod można znaleźć pod adresem
http://faisalbhagat.blogspot.com/2013/09/java-uploading-file-remotely-via-scp.html
źródło
Oto przykład przesyłania pliku za pomocą JSch :
ScpUploader.java
:import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpException; import java.io.ByteArrayInputStream; import java.util.Properties; public final class ScpUploader { public static ScpUploader newInstance() { return new ScpUploader(); } private volatile Session session; private volatile ChannelSftp channel; private ScpUploader(){} public synchronized void connect(String host, int port, String username, String password) throws JSchException { JSch jsch = new JSch(); Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session = jsch.getSession(username, host, port); session.setPassword(password); session.setConfig(config); session.setInputStream(System.in); session.connect(); channel = (ChannelSftp) session.openChannel("sftp"); channel.connect(); } public synchronized void uploadFile(String directoryPath, String fileName, byte[] fileBytes, boolean overwrite) throws SftpException { if(session == null || channel == null) { System.err.println("No open session!"); return; } // a workaround to check if the directory exists. Otherwise, create it channel.cd("/"); String[] directories = directoryPath.split("/"); for(String directory : directories) { if(directory.length() > 0) { try { channel.cd(directory); } catch(SftpException e) { // swallowed exception System.out.println("The directory (" + directory + ") seems to be not exist. We will try to create it."); try { channel.mkdir(directory); channel.cd(directory); System.out.println("The directory (" + directory + ") is created successfully!"); } catch(SftpException e1) { System.err.println("The directory (" + directory + ") is failed to be created!"); e1.printStackTrace(); return; } } } } channel.put(new ByteArrayInputStream(fileBytes), directoryPath + "/" + fileName, overwrite ? ChannelSftp.OVERWRITE : ChannelSftp.RESUME); } public synchronized void disconnect() { if(session == null || channel == null) { System.err.println("No open session!"); return; } channel.exit(); channel.disconnect(); session.disconnect(); channel = null; session = null; } }
AppEntryPoint.java
:import com.jcraft.jsch.JSchException; import com.jcraft.jsch.SftpException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public final class AppEntryPoint { private static final String HOST = "192.168.1.1"; private static final int PORT = 22; private static final String USERNAME = "root"; private static final String PASSWORD = "root"; public static void main(String[] args) throws IOException { ScpUploader scpUploader = ScpUploader.newInstance(); try { scpUploader.connect(HOST, PORT, USERNAME, PASSWORD); } catch(JSchException e) { System.err.println("Failed to connect the server!"); e.printStackTrace(); return; } System.out.println("Successfully connected to the server!"); byte[] fileBytes = Files.readAllBytes(Paths.get("C:/file.zip")); try { scpUploader.uploadFile("/test/files", "file.zip", fileBytes, true); // if overwrite == false, it won't throw exception if the file exists System.out.println("Successfully uploaded the file!"); } catch(SftpException e) { System.err.println("Failed to upload the file!"); e.printStackTrace(); } scpUploader.disconnect(); } }
źródło
-: Trochę poprawiając odpowiedź Fernando, jeśli używasz Mavena do zarządzania zależnościami: -
pom.xml :
Dodaj tę zależność w swoim projekcie. Najnowszą wersję można znaleźć tutaj .
Kod Java :
public void scpUpload(String source, String destination) { Scp scp = new Scp(); scp.setPort(port); scp.setLocalFile(source); scp.setTodir(username + ":" + password + "@" + host + ":" + destination); scp.setProject(new Project()); scp.setTrust(true); scp.execute(); }
źródło
Napisałem serwer scp, który jest znacznie łatwiejszy niż inne. Do jej rozwijania używam projektu Apache MINA (Apache SSHD). Możesz zajrzeć tutaj: https://github.com/boomz/JSCP Możesz również pobrać plik jar z
/jar
katalogu. Jak używać? Spójrz na: https://github.com/boomz/JSCP/blob/master/src/Main.javaźródło
Muszę rekurencyjnie kopiować folder, po wypróbowaniu różnych rozwiązań, ostatecznie kończy się na ProcessBuilder + oczekiwanie / spawn
scpFile("192.168.1.1", "root","password","/tmp/1","/tmp"); public void scpFile(String host, String username, String password, String src, String dest) throws Exception { String[] scpCmd = new String[]{"expect", "-c", String.format("spawn scp -r %s %s@%s:%s\n", src, username, host, dest) + "expect \"?assword:\"\n" + String.format("send \"%s\\r\"\n", password) + "expect eof"}; ProcessBuilder pb = new ProcessBuilder(scpCmd); System.out.println("Run shell command: " + Arrays.toString(scpCmd)); Process process = pb.start(); int errCode = process.waitFor(); System.out.println("Echo command executed, any errors? " + (errCode == 0 ? "No" : "Yes")); System.out.println("Echo Output:\n" + output(process.getInputStream())); if(errCode != 0) throw new Exception(); }
źródło