tra-loi-cau-hoi-phat-trien-web.com

scp qua java

Phương pháp tốt nhất để thực hiện chuyển giao scp qua ngôn ngữ lập trình Java là gì? Có vẻ như tôi có thể thực hiện điều này thông qua các thư viện JSSE, JSch hoặc lâu đài bouncy Java. Không có giải pháp nào trong số này dường như có một câu trả lời dễ dàng.

73
Lloyd Meinholz

Tôi đã kết thúc bằng cách sử dụng Jsch - nó khá đơn giản và dường như mở rộng khá tốt (tôi đã lấy vài nghìn tệp mỗi vài phút).

52
Tim Howland

cắm: sshj là sự lựa chọn lành mạnh duy nhất! Xem các ví dụ này để bắt đầu: tải xuống , tải lên .

20
shikhar

Hãy xem tại đây

Đó là mã nguồn cho nhiệm vụ SCP của Kiến. Mã trong phương thức "thực thi" là nơi các đai ốc và bu lông của nó. Điều này sẽ cung cấp cho bạn một ý tưởng công bằng về những gì được yêu cầu. Nó sử dụng JSch tôi tin.

Ngoài ra, bạn cũng có thể trực tiếp thực hiện tác vụ Ant này từ mã Java.

16
abarax

Tôi đã bọc Jsch bằng một số phương thức tiện ích để làm cho nó thân thiện hơn một chút và gọi nó

Jscp

Có sẵn tại đây: https://github.com/willwarren/jscp

Tiện ích SCP để tar một thư mục, Zip nó và quét nó ở đâu đó, sau đó giải nén nó.

Sử dụng:

// 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") 
           );

Cũng bao gồm các lớp hữu ích - Scp và Exec, và TarAndGzip, hoạt động theo cách tương tự.

6
Will

Đây là giải pháp cấp cao , không cần phải phát minh lại. Nhanh chóng và hèn hạ!

1) Trước tiên, hãy truy cập http://ant.Apache.org/bindoad.cgi và tải xuống tệp nhị phân Apache Ant mới nhất . (ngày nay, Apache-ant-1.9.4-bin.Zip).

2) Trích xuất tệp đã tải xuống và tìm JAR ant-jsch.jar ("Apache-ant-1.9.4/lib/ant-jsch.jar"). Thêm JAR này trong dự án của bạn . Ngoài ra ant-launcher.jar và ant.jar.

3) Chuyển đến Dự án Jcraft jsch SouceForge và tải xuống bình. Ngày nay, jsch-0.1.52.jar . Ngoài ra Thêm JAR này trong dự án của bạn .

Bây giờ, bạn có thể dễ dàng sử dụng vào Java mã Ant Classes Scp để sao chép tệp qua mạng hoặc SSHExec cho các lệnh trong máy chủ SSH.

4) Ví dụ mã 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();
4
Fernando Santos

dự án openssh liệt kê một số Java thay thế, Trilead SSH cho Java có vẻ phù hợp với những gì bạn đang yêu cầu.

3
Kyle Burton

Tôi đã xem xét rất nhiều giải pháp này và không thích nhiều giải pháp trong số đó. Chủ yếu là vì bước khó chịu khi phải xác định máy chủ đã biết của bạn. Điều đó và JSCH ở mức thấp đến mức nực cười so với lệnh scp.

Tôi đã tìm thấy một thư viện không yêu cầu điều này nhưng nó được đóng gói và sử dụng như một công cụ dòng lệnh. https://code.google.com.vn/p/scp-Java-client/

Tôi đã xem qua mã nguồn và phát hiện ra cách sử dụng nó mà không cần dòng lệnh. Đây là một ví dụ về tải lên:

    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("[email protected]:/path/on/remote");
    scp.execute();

Nhược điểm lớn nhất là nó không nằm trong repo maven (mà tôi có thể tìm thấy). Nhưng, sự dễ dàng sử dụng là giá trị nó với tôi.

2
Daniel Kaplan

Tôi sử dụng API SFTP này có SCP được gọi là Zehon, thật tuyệt, rất dễ sử dụng với nhiều mã mẫu. Đây là trang http://www.zehon.com

2
bigjavageek

Giống như một số ở đây, cuối cùng tôi đã viết một trình bao bọc xung quanh thư viện JSch.

Nó được gọi là way-secshell và nó được lưu trữ trên 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();
1
user717263

JSch là một thư viện đẹp để làm việc. Nó có một câu trả lời khá dễ dàng cho câu hỏi của bạn.

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);
    }
  }

Bạn có thể tìm thấy mã hoàn chỉnh tại

http://faisalbhagat.blogspot.com/2013/09/Java-uploading-file-rem Remote-via-scp.html

0
faisalbhagat

Dưới đây là một ví dụ để tải lên một tệp bằng cách sử dụng 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();
    }
}
0
Eng.Fouad

Tôi đã viết một máy chủ scp dễ dàng hơn nhiều so với những người khác. Tôi sử dụng dự án Apache MINA (Apache SSHD) để phát triển nó. Bạn có thể xem tại đây: https://github.com/boomz/JSCP Ngoài ra, bạn có thể tải xuống tệp jar từ /jar danh mục. Sử dụng như thế nào? Hãy xem trên: https://github.com/boomz/JSCP/blob/master/src/Main.Java

0
boomz

jsCH đã làm việc rất tốt cho tôi. Dưới đây là một ví dụ về phương pháp sẽ kết nối với máy chủ sftp và tải các tệp vào thư mục được chỉ định. Bạn nên tránh xa việc vô hiệu hóa StricthostKeyChecking. Mặc dù khó thiết lập hơn một chút, vì lý do bảo mật chỉ định các máy chủ đã biết nên là chuẩn mực.

jsch.setKnownhosts ("C:\Users\test\unknown_hosts"); được đề xuất

JSch.setConfig ("StricthostKeyChecking", "không"); - không được đề xuất

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();
            }
        }

    }
0
Eduardo Dennis

Tôi cần sao chép thư mục một cách đệ quy, sau khi thử các giải pháp khác nhau, cuối cùng kết thúc bằng ProcessBuilder + mong đợi/sinh sản

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 %[email protected]%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();
}
0
Burt