Який найкращий спосіб виконувати передачу scp за допомогою мови програмування Java? Здається, я зможу виконати це за допомогою JSSE, JSch або жвавих замкових Java-бібліотек. Здається, жодне з цих рішень не має простої відповіді.
Який найкращий спосіб виконувати передачу scp за допомогою мови програмування Java? Здається, я зможу виконати це за допомогою JSSE, JSch або жвавих замкових Java-бібліотек. Здається, жодне з цих рішень не має простої відповіді.
Відповіді:
У підсумку я використав Jsch - це було досить просто і, здавалося, досить добре масштабувалось (я захоплював кілька тисяч файлів кожні кілька хвилин).
plug: sshj - єдиний розумний вибір! Для початку перегляньте ці приклади: завантажте , завантажте .
Я обгорнув Jsch деякими корисними методами, щоб зробити його дещо зручнішим, і назвав його
Доступно тут: https://github.com/willwarren/jscp
Утиліта SCP, щоб видалити папку, заархівувати її та десь переписати, а потім розпакувати.
Використання:
// 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")
);
Також включає корисні класи - Scp та Exec, і TarAndGzip, які працюють приблизно однаково.
Це рішення високого рівня , не потрібно винаходити. Швидко і брудно!
1) Спочатку перейдіть на веб-сайт http://ant.apache.org/bindownload.cgi та завантажте найновіший двійковий файл Apache Ant. (нині apache-ant-1.9.4-bin.zip).
2) Витягніть завантажений файл і знайдіть JAR ant-jsch.jar ("apache-ant-1.9.4 / lib / ant-jsch.jar"). Додайте цей JAR у свій проект . Також ant-launcher.jar та ant.jar.
3) Перейдіть до Jcraft jsch SouceForge Project і завантажте банку. У наш час jsch-0.1.52.jar . Також додайте цей JAR у свій проект .
Тепер ви можете легко використовувати в Java-коді Ant Classes Scp для копіювання файлів через мережу або SSHExec для команд на серверах SSH.
4) Приклад коду 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();
У проекті openssh перелічено кілька альтернативних варіантів Java, Trilead SSH для Java, здається, відповідає тому, про що ви просите.
Я використовую цей SFTP API, який має SCP під назвою Zehon, він чудовий, настільки простий у використанні з великою кількістю зразків коду. Ось сайт http://www.zehon.com
Я розглянув багато цих рішень і багато з них мені не сподобались. Здебільшого тому, що дратує крок того, що потрібно ідентифікувати своїх відомих господарів. Це і JSCH знаходиться на смішно низькому рівні щодо команди scp.
Я знайшов бібліотеку, яка цього не вимагає, але вона в комплекті і використовується як інструмент командного рядка. https://code.google.com/p/scp-java-client/
Я переглянув вихідний код і виявив, як використовувати його без командного рядка. Ось приклад завантаження:
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();
Найбільший мінус полягає в тому, що справа не в maven-репо (яке я міг знайти). Але простота використання мені того варта.
jsCH чудово для мене спрацював. Нижче наведено приклад методу, який буде підключатися до сервера sftp і завантажувати файли до вказаного каталогу. Рекомендуємо триматися подалі від вимкнення StrictHostKeyChecking. Хоча трохи складніше налаштувати, з міркувань безпеки вказівка відомих хостів має бути нормою.
jsch.setKnownHosts ("C: \ Users \ test \ known_hosts"); рекомендується
JSch.setConfig ("StrictHostKeyChecking", "ні"); - не рекомендовано
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();
}
}
}
Як і деякі тут, я закінчив писати обгортку навколо бібліотеки JSch.
Це називається way-secshell, і воно розміщується на 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();
JSch - приємна бібліотека для роботи. Він має досить просту відповідь на ваше запитання.
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);
}
}
Ви можете знайти повний код за адресою
http://faisalbhagat.blogspot.com/2013/09/java-uploading-file-remotely-via-scp.html
Ось приклад завантаження файлу за допомогою 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();
}
}
-: Трохи уточнивши відповідь Фернандо, якщо ви використовуєте Maven для управління залежностями: -
pom.xml :
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-jsch</artifactId>
<version>${ant-jsch.version}</version>
</dependency>
Додайте цю залежність у свій проект. Останню версію можна знайти тут .
Код 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();
}
Я написав сервер scp, який набагато простіший за інші. Я розробляю проект Apache MINA (Apache SSHD). Ви можете подивитися тут: https://github.com/boomz/JSCP
Також ви можете завантажити файл jar з /jar
каталогу. Як користуватись? Погляньте на: https://github.com/boomz/JSCP/blob/master/src/Main.java
Мені потрібно скопіювати папку рекурсивно, після випробування різних рішень, нарешті, в кінцевому підсумку ProcessBuilder + очікування / поява
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();
}