通过 SFTP 传输文件
transfer file through SFTP
我想通过 SFTP 传输文件。我发现了 how to transfer a file through SFTP in java? 提出的类似问题。我在本地主机上尝试了 post 中建议的解决方案。但是我在输出下显示了以下错误。
输出
preparing the host information for sftp.
Host connected.
sftp channel opened and connected.
2: No such file
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2846)
at com.jcraft.jsch.ChannelSftp._realpath(ChannelSftp.java:2340)
at com.jcraft.jsch.ChannelSftp.cd(ChannelSftp.java:342)
at ScpTo.main(ScpTo.java:69)
File transfered successfully to host.
sftp Channel exited.
Channel disconnected.
Host Session disconnected.
代码
import java.io.File;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import com.jcraft.jsch.Channel;
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;
public class ScpTo {
/**
*
*/
public ScpTo() {
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args) {
String SFTPHOST = "192.168.1.3";
int SFTPPORT = 22;
String SFTPUSER = "sam-PC";
String SFTPPASS = "";
String SFTPWORKINGDIR = "C:/Users/sam/Desktop/hi.txt";
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
System.out.println("preparing the host information for sftp.");
JSch jsch = new JSch();
try {
session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT);
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
session.setPassword(SFTPPASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
try {
session.connect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Host connected.");
try {
channel = session.openChannel("sftp");
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
channel.connect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("sftp channel opened and connected.");
channelSftp = (ChannelSftp) channel;
try {
channelSftp.cd(SFTPWORKINGDIR);
} catch (SftpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File f = new File(SFTPWORKINGDIR);
try {
channelSftp.put(new FileInputStream(f), f.getName());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SftpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("File transfered successfully to host.");
channelSftp.exit();
System.out.println("sftp Channel exited.");
channel.disconnect();
System.out.println("Channel disconnected.");
session.disconnect();
System.out.println("Host Session disconnected.");
}
}
堆栈跟踪显示错误发生在执行 cd 命令期间。错误是 "no such file",这可能实际上意味着 "no such directory",所以问题几乎可以肯定是 SFTPWORKINGDIR 定义的目录不存在。
不过我不怪你糊涂。 API 看起来非常复杂。我是 edtFTPj/PRO 的开发者之一,它提供了一个更简单的界面。例如,下面是通过 SFTP 下载文件的代码:
SecureFileTransferClient client = new SecureFileTransferClient();
client.setProtocol(Protocol.SFTP);
client.setRemoteHost("myserver.com");
client.setUserName("myusername");
client.setPassword("mypassword");
client.connect();
client.downloadFile("filename.txt", "filename.txt");
client.disconnect();
请注意 edtFTPj/PRO 不是免费产品。
String SFTPWORKINGDIR = "C:/Users/sam/Desktop/hi.txt";
...
channelSftp.cd(SFTPWORKINGDIR);
首先,SFTPWORKINGDIR
似乎指的是文件,而不是目录。您可能正在尝试 cd
到某个文件,或者应该是一个文件。
其次,SFTP 使用类似 unix 的路径名模型。以“/”开头的路径名是绝对路径,从服务器的根目录解析。不以“/”开头的路径是相对路径,从您的 SFTP 会话开始的目录(通常是您在服务器上登录的帐户的主目录)解析。
您的 SFTPWORKINGDIR
值是 windows 格式路径,而不是 unix 格式路径。 SFTP 服务器很可能没有按照您的意图解释它,即使该 SFTP 服务器在 Windows 系统上是 运行。您应该查阅 SFTP 服务器的文档并将路径名转换为正确的形式以访问所需的目录。如果 SFTP 服务器是 Cygwin openssh 服务器,我相信正确的形式应该是“/cygdrive/c/Users/sam/Desktop”。
这是一个完整的 'upload code',其中包含从 windows 机器到 linux 机器的身份验证。此代码从您的机器 (win) 的特定位置上传文件并上传到 FTP 服务器。这是我为我的问题申请的解决方案。如果有人看到问题,请发表评论。
try {
JSch jsch = new JSch();
Session session = jsch.getSession( "<userName>", "<ip_block>", 22 );
session.setConfig( "PreferredAuthentications", "password" );
session.setPassword( "<pasword>" );
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");//do not prefer this. demo only
session.setConfig(config);
session.connect( 1200 );
Channel channel = session.openChannel( "sftp" );
ChannelSftp sftp = ( ChannelSftp ) channel;
sftp.connect( 600 );
channel = session.openChannel("sftp");
channel.connect();
try {
File f = new File("E:/apache-tomcat-7.0.65/bin/" + this.fileName);
sftp.put(new FileInputStream(f), f.getName());
} catch (Exception e) {
e.printStackTrace();
}
channel.disconnect();
sftp.disconnect();
} catch (JSchException e) {
e.printStackTrace();
}
我想通过 SFTP 传输文件。我发现了 how to transfer a file through SFTP in java? 提出的类似问题。我在本地主机上尝试了 post 中建议的解决方案。但是我在输出下显示了以下错误。
输出
preparing the host information for sftp.
Host connected.
sftp channel opened and connected.
2: No such file
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2846)
at com.jcraft.jsch.ChannelSftp._realpath(ChannelSftp.java:2340)
at com.jcraft.jsch.ChannelSftp.cd(ChannelSftp.java:342)
at ScpTo.main(ScpTo.java:69)
File transfered successfully to host.
sftp Channel exited.
Channel disconnected.
Host Session disconnected.
代码
import java.io.File;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import com.jcraft.jsch.Channel;
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;
public class ScpTo {
/**
*
*/
public ScpTo() {
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args) {
String SFTPHOST = "192.168.1.3";
int SFTPPORT = 22;
String SFTPUSER = "sam-PC";
String SFTPPASS = "";
String SFTPWORKINGDIR = "C:/Users/sam/Desktop/hi.txt";
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
System.out.println("preparing the host information for sftp.");
JSch jsch = new JSch();
try {
session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT);
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
session.setPassword(SFTPPASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
try {
session.connect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Host connected.");
try {
channel = session.openChannel("sftp");
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
channel.connect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("sftp channel opened and connected.");
channelSftp = (ChannelSftp) channel;
try {
channelSftp.cd(SFTPWORKINGDIR);
} catch (SftpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File f = new File(SFTPWORKINGDIR);
try {
channelSftp.put(new FileInputStream(f), f.getName());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SftpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("File transfered successfully to host.");
channelSftp.exit();
System.out.println("sftp Channel exited.");
channel.disconnect();
System.out.println("Channel disconnected.");
session.disconnect();
System.out.println("Host Session disconnected.");
}
}
堆栈跟踪显示错误发生在执行 cd 命令期间。错误是 "no such file",这可能实际上意味着 "no such directory",所以问题几乎可以肯定是 SFTPWORKINGDIR 定义的目录不存在。
不过我不怪你糊涂。 API 看起来非常复杂。我是 edtFTPj/PRO 的开发者之一,它提供了一个更简单的界面。例如,下面是通过 SFTP 下载文件的代码:
SecureFileTransferClient client = new SecureFileTransferClient();
client.setProtocol(Protocol.SFTP);
client.setRemoteHost("myserver.com");
client.setUserName("myusername");
client.setPassword("mypassword");
client.connect();
client.downloadFile("filename.txt", "filename.txt");
client.disconnect();
请注意 edtFTPj/PRO 不是免费产品。
String SFTPWORKINGDIR = "C:/Users/sam/Desktop/hi.txt";
...
channelSftp.cd(SFTPWORKINGDIR);
首先,SFTPWORKINGDIR
似乎指的是文件,而不是目录。您可能正在尝试 cd
到某个文件,或者应该是一个文件。
其次,SFTP 使用类似 unix 的路径名模型。以“/”开头的路径名是绝对路径,从服务器的根目录解析。不以“/”开头的路径是相对路径,从您的 SFTP 会话开始的目录(通常是您在服务器上登录的帐户的主目录)解析。
您的 SFTPWORKINGDIR
值是 windows 格式路径,而不是 unix 格式路径。 SFTP 服务器很可能没有按照您的意图解释它,即使该 SFTP 服务器在 Windows 系统上是 运行。您应该查阅 SFTP 服务器的文档并将路径名转换为正确的形式以访问所需的目录。如果 SFTP 服务器是 Cygwin openssh 服务器,我相信正确的形式应该是“/cygdrive/c/Users/sam/Desktop”。
这是一个完整的 'upload code',其中包含从 windows 机器到 linux 机器的身份验证。此代码从您的机器 (win) 的特定位置上传文件并上传到 FTP 服务器。这是我为我的问题申请的解决方案。如果有人看到问题,请发表评论。
try {
JSch jsch = new JSch();
Session session = jsch.getSession( "<userName>", "<ip_block>", 22 );
session.setConfig( "PreferredAuthentications", "password" );
session.setPassword( "<pasword>" );
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");//do not prefer this. demo only
session.setConfig(config);
session.connect( 1200 );
Channel channel = session.openChannel( "sftp" );
ChannelSftp sftp = ( ChannelSftp ) channel;
sftp.connect( 600 );
channel = session.openChannel("sftp");
channel.connect();
try {
File f = new File("E:/apache-tomcat-7.0.65/bin/" + this.fileName);
sftp.put(new FileInputStream(f), f.getName());
} catch (Exception e) {
e.printStackTrace();
}
channel.disconnect();
sftp.disconnect();
} catch (JSchException e) {
e.printStackTrace();
}