views:

18

answers:

2

I think I understand the difference between ASCII mode and Binary mode on regular FTP transfers -- in Binary mode the file is copied exactly, and in ASCII mode the client may modify line endings (stripping the Carriage Return from Windows -> UNIX or adding it in the other direction). However, I thought that the SFTP protocol only supported Binary mode style transfers; the source file would not be modified.

However, when using the JSch library to copy a file from Windows to UNIX, the Windows-style line endings are stripped. This is problematic because these files are retrieved by others, using various methods, for Windows machines, and I can't guarantee that their clients will re-add the Carriage Return before each Line Feed.

Properties properties = new Properties();
properties.setProperty("StrictHostKeyChecking", "no");
Session session = jsch.getSession(UserName, Address, Port);
session.setPassword(Password);
session.setConfig(properties);
session.connect();
ChannelSftp channel = (ChannelSftp)session.openChannel("sftp");
channel.connect();
channel.
channel.cd(SCPDir);
channel.put(new ByteArrayInputStream(WindowsStyleString.getBytes()), FileName);
channel.disconnect();
session.disconnect();

Is there something I can do to ensure that JSch transfers the files exactly? It is frustratingly lacking in documentation, so I'm not sure if there's some parameter of its or perhaps some additional SSH property I can specify to ensure verbatim transfer. And why is this even happening in the first place, when ASCII mode style modifications aren't part of the SFTP standard?

+1  A: 

SFTP supported only binary mode until version 4 and in version 4 and later (5, 6) binary mode is still default, though ASCII mode is available too. Whatever JSh does with your file is it's own initiative. Maybe it strips CRs itself, or maybe the server does this, I can't say for sure without seeing any kind of log that Jsh or server exposes.

Eugene Mayevski 'EldoS Corp
I'd glossed over the JSch code and didn't see anything that modified the source String, but I couldn't actually step through it until now. And sure enough... it didn't replace anything!I'm starting to feel like a bad Stack Exchanger, since this is the third time I've answered my own question. I didn't realize that toString returns a string without the \r on UNIX systems, and it just so happens that every other module I've used (FTP, SQL, eMail) has either automatically added it or didn't require it. So I didn't think to check the source string directly, since it worked in every other format.
Hammer Bro.
Do I understand right, that you looked at string in debugger and it confused you?
Eugene Mayevski 'EldoS Corp
A: 

Another case of misdirection; I apologize for all of these unsatisfactory questions.

It turns out that on Windows, where I can debug, Java's ubiquitous toString returns line endings with the Carriage Return and Line Feed (\r\n). On the Linux production servers, toString returns only \n. However, every use I had of these toString objects, whether uploaded via FTP (even though the host is also a Linux machine), e-mailed, or used in SQL queries, either automatically appended \r or didn't require it. But SFTP didn't.

So I guess the lesson here is that toString probably returns a platform-appropriate line ending format, that org.apache.commons.net.ftp.FTPClient in ASCII mode will add \r before \n even if the FTP server is hosted on Linux (or perhaps that server is masquerading as Windows), and that e-mail and SQL don't particularly care which line endings they have.

Hammer Bro.