Java 通过 SFTP 传输文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30397692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
transfer file through SFTP
提问by user2211678
I want to transfer a file through SFTP. I found a similar question that is asked from how to transfer a file through SFTP in java?. I tried out the suggested solution from the post on localhost. but I get the following error shown under output.
我想通过 SFTP 传输文件。我发现了一个类似的问题,该问题来自如何在 java 中通过 SFTP 传输文件?. 我从本地主机上的帖子中尝试了建议的解决方案。但我在输出下显示以下错误。
output
输出
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.
Code
代码
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.");
}
}
采纳答案by HansA
The stack-trace shows that the error happened during execution of the cd command. The error is "no such file", which probably actually means "no such directory", so the problem is almost certainly that the directory defined by SFTPWORKINGDIR doesn't exist.
堆栈跟踪显示错误发生在执行 cd 命令期间。错误是“没有这样的文件”,这可能实际上意味着“没有这样的目录”,所以问题几乎肯定是由 SFTPWORKINGDIR 定义的目录不存在。
I don't blame you for being confused, though. That API seems to be hellishly complicated. I'm one of the developers of edtFTPj/PRO, which offers a much simpler interface. For example, here's code to download a file over SFTP:
不过,我不怪你糊涂了。该 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();
Note that edtFTPj/PRO is not a free product.
请注意,edtFTPj/PRO 不是免费产品。
回答by Kenster
String SFTPWORKINGDIR = "C:/Users/sam/Desktop/hi.txt";
...
channelSftp.cd(SFTPWORKINGDIR);
To start with, SFTPWORKINGDIR
appears to refer to a file, not a directory. You may be trying to cd
to something that's a file, or that's supposed to be a file.
首先,SFTPWORKINGDIR
似乎是指文件,而不是目录。您可能正在尝试使用cd
某个文件或应该是文件的内容。
Second, SFTP uses a unix-like model for pathnames. Pathnames which begin with "/" are absolute paths and are resolved from the server's root directory. Paths which don't begin with "/" are relative paths, and are resolved from the directory where your SFTP session started (usually the home directory for the account that you logged into on the server).
其次,SFTP 使用类似 Unix 的路径名模型。以“/”开头的路径名是绝对路径,从服务器的根目录解析。不以“/”开头的路径是相对路径,并从您的 SFTP 会话开始的目录(通常是您登录到服务器的帐户的主目录)解析。
Your value of SFTPWORKINGDIR
is a windows-format path, not a unix-format path. It's very likely that the SFTP server isn't interpreting it as you intend, even if that SFTP server is running on a Windows system. You should consult the documentation for your SFTP server and convert the pathname into the proper form to access the directory that you want. If the SFTP server is the Cygwin openssh server, I believe the right form will be something like "/cygdrive/c/Users/sam/Desktop".
您的值SFTPWORKINGDIR
是 windows 格式的路径,而不是 unix 格式的路径。即使 SFTP 服务器在 Windows 系统上运行,SFTP 服务器也很可能没有按照您的意图解释它。您应该查阅 SFTP 服务器的文档并将路径名转换为正确的格式以访问您想要的目录。如果 SFTP 服务器是 Cygwin openssh 服务器,我相信正确的形式将类似于“/cygdrive/c/Users/sam/Desktop”。
回答by comitatenses
Here is a complete 'upload code' with authentication from a windows machine to linux machine. this code uploads file from specific location from your machine(win) and uploads to FTP server. This is my solution that i applied for my problem. if somebody sees problem, please comment.
这是一个完整的“上传代码”,带有从 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();
}