How to tell if an SFTP upload was successful using JSch

java, jsch, sftp

Solution

I guess if a SFTPException is thrown that's unsuccessful otherwise i can assume it was successful?

That is correct. The various `ChannelSftp.put()` functions will throw an exception if they fail for any reason. If you want to double-check, you could call `ChannelSftp.stat()` or `...lstat()` on the remote filename afterwards to check it. But be aware that another process could hypothetically delete or move the remote file before you got a chance to check it.

You don't normally need to access the input or output streams of a `ChannelSftp`. `getExitStatus()` would tell you the exit status of the SFTP session as a whole, rather than the result of a particular operation.

JCraft has an example program illustrating how to do SFTP that you might find useful.

Problem

Unfortunately the `getExitStatus()` method always returns -1 so i can't use that to tell me whether or not a file upload worked. I tried to use the `getInputStream()` method of the `Channel` class but whenever i tried to read from the inputstream my code blocked forever as if the `Channel` instance was still open/connected (even though the `isConnected` and `isClosed()` were false and true respectively - suggesting that the Channel was indeed closed). The following code always blocks after i try to read a byte of data from the input stream: ``` public class Put { public static void main(String[] args) throws IOException { Session session = null; Channel channel = null; ChannelSftp channelSftp = null; InputStream in = null; JSch jsch = new JSch(); try { jsch.setKnownHosts("known_hosts"); session = jsch.getSession("user", "host", 22); session.setPassword("password"); session.connect(); channel = session.openChannel("sftp"); channel.setInputStream(null); stdout = channel.getInputStream(); channel.connect(); channelSftp = (ChannelSftp)channel; channelSftp.cd("/path/to/sftp"); channelSftp.put("/path/to/localfile", "/path/to/remotefile"); } catch (JSchException e) { System.out.println(e.getMessage()); e.printStackTrace(); } catch (SftpException e) { System.out.println(e.id); System.out.println(e.getMessage()); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if(channelSftp != null && channelSftp.isConnected())channelSftp.exit(); if(channel != null && channel.isConnected()) channel.disconnect(); if(session != null && session.isConnected()) session.disconnect(); } System.out.println("Channel is connected? " + channel.isConnected()); // returns false as i would expect System.out.println("Channel is closed? " + channel.isClosed()); // returns true as i would expect System.out.println(stdout.available()); // returns 0 System.out.println(stdout.read()); // code blocks here } } ``` I suppose my questions are: Why is my code blocking whenever i try to read from the input stream (even though the `Channel` is indeed closed) What is the way to tell if a file upload worked or not. I guess if a SFTPException is thrown that's unsuccessful otherwise i can assume it was successful?

Original source