This question already has answers here:
How to retrieve a file from a server via SFTP?
(16 answers)
Closed 6 years ago.
How to transfer a file through SFTP in java? I want sample code for SFTP client.
I want to embed the SFTP server in my application and the client should able to send a file to my application.
PS: This was asked for SFTP client. And This question is not a duplicate of other two questions.
Find the below link to implement SFTP.
https://codetransient.wordpress.com/2019/06/22/sftp-secured-file-transfer-protocol/
Try this code.
public void send (String fileName) {
String SFTPHOST = "host:IP";
int SFTPPORT = 22;
String SFTPUSER = "username";
String SFTPPASS = "password";
String SFTPWORKINGDIR = "file/to/transfer";
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
System.out.println("preparing the host information for sftp.");
try {
JSch jsch = new JSch();
session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT);
session.setPassword(SFTPPASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
System.out.println("Host connected.");
channel = session.openChannel("sftp");
channel.connect();
System.out.println("sftp channel opened and connected.");
channelSftp = (ChannelSftp) channel;
channelSftp.cd(SFTPWORKINGDIR);
File f = new File(fileName);
channelSftp.put(new FileInputStream(f), f.getName());
log.info("File transfered successfully to host.");
} catch (Exception ex) {
System.out.println("Exception found while tranfer the response.");
} finally {
channelSftp.exit();
System.out.println("sftp Channel exited.");
channel.disconnect();
System.out.println("Channel disconnected.");
session.disconnect();
System.out.println("Host Session disconnected.");
}
}
Related
My program opens sftp connection and connects to the server to get a file which is then processed.
I am writing a test case for this method, trying to mock the connection.
My actual class is:
public void getFile() {
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
String path = ftpurl;
try {
JSch jsch = new JSch();
session = jsch.getSession(username, host, port);
session.setConfig("StrictHostKeyChecking", "no");session.setPassword(JaspytPasswordEncryptor.getDecryptedString(jaspytEncryptionKey, jaspytEncryptionAlgorithm, password));
session.connect();
channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp) channel;
channelSftp.cd(path);
Vector<ChannelSftp.LsEntry> list = channelSftp.ls("*.csv");
for (ChannelSftp.LsEntry entry : list) {
if (entry.getFilename().startsWith("A...")) {
findByFileName(entry.getFilename());
}
}
channelSftp.exit();
session.disconnect();
} catch (JSchException e) {
LOGGER.error("JSch exception"+e);
} catch (SftpException e) {
LOGGER.error("Sftp Exception"+e);
}
}
Test class so far:
#Test
public void getNamesTestValid() throws IOException, JSchException {
JSch jsch = new JSch();
Hashtable config = new Hashtable();
config.put("StrictHostKeyChecking", "no");
JSch.setConfig(config);
Session session = jsch.getSession( "remote-username", "localhost", 22999);
session.setPassword("remote-password");
session.connect();
Channel channel = session.openChannel( "sftp" );
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
Mockito.when(fileRepository.findByFileName(fileName)).thenReturn(fileDetail);
scheduler.getCSVFileNames();
}
When trying to mock the connection, it searches for the actual port and the error is port invalid, connection refused.
I only want to mock the connection.
My other doubt is after mocking the connection from where should i read the file details.
That's because you're creating an actual connection with new Jsch(). You need to mock the connection with a library such as Mockito. For example:
#RunWith(MockitoJUnitRunner.class)
class Test {
#Mock(answer = Answers.RETURNS_DEEP_STUBS)
private JSch mockJsch;
..
void test() {
Session mockSession = mockJsch.getSession("username", "localhost", 22999);
..
}
}
My file transfer to SFTP server is failing with exception: java.io.IOException: inputstream is closed
My code has been working for the last 1 year or so, without any issues.
Nor I did any code change.
This has been happening since last three days.
I tried to check if there was any changes to the Library in the last few days and there have been none, also I'm using the latest one : jsch-0.1.54.jar
Here is my code:
public void sendVsbFile(String fileName, MyObject c) {
File f = new File(fileName);
if (f.exists()) {
String SFTPHOST = c.SFTPURL;
int SFTPPORT = Integer.parseInt(c.SFTPPORT);
String SFTPUSER = c.SFTPUserName;
String SFTPPASS = c.SFTPPassword;
String SFTPWORKINGDIR = c.FTPFolderLocation;
Session session;
Channel channel;
ChannelSftp channelSftp;
try {
JSch jsch = new JSch();
session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT);
session.setPassword(SFTPPASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
config.put("TCPKeepAlive", "yes");
session.setConfig(config);
session.setServerAliveInterval(120 * 1000);
session.setServerAliveCountMax(1000);
session.setTimeout(timeout);
session.connect();
System.out.println("Host connected.");
channel = session.openChannel("sftp");
channelSftp = (ChannelSftp) channel;
channelSftp.connect();
System.out.println("sftp channel opened and connected.");
channelSftp.cd(SFTPWORKINGDIR);
channelSftp.cd(Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyLocalAndroidPath/");
String suffix = ".filepart";
Log.d(TAG, "file name = " + f.getName());
String tempFileName = f.getName() + suffix;
channelSftp.put(new FileInputStream(f), tempFileName, ChannelSftp.RESUME);
String newFileName = tempFileName.substring(0, tempFileName.length() - suffix.length());
channelSftp.rename(tempFileName, newFileName);
System.out.println("File transferred successfully to host.");
} catch (JSchException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
}
}
Many developers have posted this kind of issue, but there's no concrete solution provided. Please if anyone has ever faced this issue before, do help. Thanks.
Here is the Stack Trace:
java.io.IOException: inputstream is closed
at com.jcraft.jsch.ChannelSftp._put(ChannelSftp.java:697)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:475)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:365)
at myMethod(MyClass.java:933)
at myMethod.run(MyClass.java:804)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.io.IOException: inputstream is closed
at com.jcraft.jsch.ChannelSftp.fill(ChannelSftp.java:2911)
at com.jcraft.jsch.ChannelSftp.header(ChannelSftp.java:2935)
at com.jcraft.jsch.ChannelSftp.checkStatus(ChannelSftp.java:2473)
at com.jcraft.jsch.ChannelSftp._put(ChannelSftp.java:686)
... 5 more
I'm trying to use JSch to transfer files from a remote machine, whenever I execute the code I get the exception "com.jcraft.jsch.JSchException: connection is closed by foreign host". My code is given below, it doesn't even print "session established", so I thing the problem is at seeion.connetct();
Please help.
String SFTPHOST ="hostname";
int SFTPPORT = 23;
String SFTPUSER = "user";
String SFTPPASS = "passwrd";
String source ="source file";
Stirng dest ="destination";
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
try{
JSch jsch = new JSch();
session = jsch.getSession(SFTPUSER,SFTPHOST,SFTPPORT);
session.setPassword(SFTPPASS);
session.connect();
System.out.println("session connected...");
channel = session.openChannel("sftp");
channel.connect();
System.out.println("channel connected...");
channelSftp = (ChannelSftp)channel;
channelSftp.get(source,dest);
System.out.println("Transfer completed");
}catch(Exception ex){
ex.printStackTrace();
}
I am currently doing a SFTP file transfer using JSch as follows,
public void send (String fileName) {
String SFTPHOST = "host:IP";
int SFTPPORT = 22;
String SFTPUSER = "username";
String SFTPPASS = "password";
String SFTPWORKINGDIR = "file/to/transfer";
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
System.out.println("preparing the host information for sftp.");
try {
JSch jsch = new JSch();
session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT);
session.setPassword(SFTPPASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
System.out.println("Host connected.");
channel = session.openChannel("sftp");
channel.connect();
System.out.println("sftp channel opened and connected.");
channelSftp = (ChannelSftp) channel;
channelSftp.cd(SFTPWORKINGDIR);
File f = new File(fileName);
channelSftp.put(new FileInputStream(f), f.getName());
log.info("File transfered successfully to host.");
} catch (Exception ex) {
System.out.println("Exception found while tranfer the response.");
}
finally{
channelSftp.exit();
System.out.println("sftp Channel exited.");
channel.disconnect();
System.out.println("Channel disconnected.");
session.disconnect();
System.out.println("Host Session disconnected.");
}
}
I need to do this transfer as a different user i.e I need to trigger pbrun first and then perform the transfer using the new user. I could not find such an option in JSch or ChannelSftp. Is it possible to do the same using the mentioned APIs.
I'm using JSch to upload files to a SFTP. It works but sometimes the TCP connection is shut down while a file is being uploaded resulting on a truncated file on the server.
I found out that the reput command on SFTP servers resumes the upload. How can I send a reput command with JSch? Is it even possible?
Here's my code:
public void upload(File file) throws Exception
{
JSch jsch = new JSch();
Session session = jsch.getSession(USER, HOST, PORT);
session.setPassword(PASSWORD);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel=session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp)channel;
sftpChannel.put(file.getAbsolutePath(), file.getName());
channel.disconnect();
session.disconnect();
}
I found a way. Use the "put" method with the RESUME parameter:
sftpChannel.put(file.getAbsolutePath(), file.getName(), ChannelSftp.RESUME);
My code became:
public static void upload(File file, boolean retry) {
try
{
System.out.println("Uplodaing file " + file.getName());
JSch jsch = new JSch();
Session session = jsch.getSession(USER, HOST, PORT);
session.setPassword(PASSWORD);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
if (!retry)
sftpChannel.put(file.getAbsolutePath(), file.getName(), ChannelSftp.OVERWRITE);
else
sftpChannel.put(file.getAbsolutePath(), file.getName(), ChannelSftp.RESUME);
channel.disconnect();
session.disconnect();
}
catch (Exception e)
{
e.printStackTrace();
upload(file, true);
}
}