in src/main/java/com/pastdev/jsch/nio/file/UnixSshFileSystemProvider.java [391:463]
public OutputStream newOutputStream( Path path, OpenOption... openOptions ) throws IOException {
UnixSshPath unixPath = checkPath( path ).toAbsolutePath();
Set<OpenOption> options = null;
if ( openOptions == null || openOptions.length == 0 ) {
options = new HashSet<OpenOption>( Arrays.asList( new StandardOpenOption[] {
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE
} ) );
logger.debug( "no open options specified, so using CREATE, TRUNCATE_EXISTING, and WRITE" );
}
else {
options = new HashSet<OpenOption>( Arrays.asList( openOptions ) );
}
if ( options.contains( StandardOpenOption.READ ) ) {
throw new IllegalArgumentException( "read not allowed on OutputStream, seriously..." );
}
if ( !options.contains( StandardOpenOption.WRITE ) ) {
throw new IllegalArgumentException( "what good is an OutputStream that you cant write to?" );
}
if ( options.contains( StandardOpenOption.DELETE_ON_CLOSE ) ) {
throw new UnsupportedOperationException( "not gonna implement" );
}
// dd has options for SYNC, DSYNC and SPARSE maybe...
try {
checkAccess( unixPath );
if ( options.contains( StandardOpenOption.CREATE_NEW ) ) {
throw new FileAlreadyExistsException( unixPath.toString() );
}
}
catch ( NoSuchFileException e ) {
if ( options.contains( StandardOpenOption.CREATE_NEW ) ) {
// this is as close to atomic create as i can get...
// TODO convert this to use `dd of=file conv=excl` and write 0
// bytes which will make the check for exists and create atomic
createFile( unixPath );
}
else if ( !options.contains( StandardOpenOption.CREATE ) ) {
throw e;
}
}
StringBuilder commandBuilder = new StringBuilder( unixPath.getFileSystem().getCommand( "cat" ) )
.append( " " );
if ( options.contains( StandardOpenOption.APPEND )
&& !options.contains( StandardOpenOption.TRUNCATE_EXISTING ) ) {
commandBuilder.append( ">> " );
}
else {
commandBuilder.append( "> " );
}
commandBuilder.append( unixPath.toAbsolutePath().quotedString() );
final ChannelExecWrapper channel = unixPath.getFileSystem()
.getCommandRunner().open( commandBuilder.toString() );
return new OutputStream() {
private OutputStream outputStream = channel.getOutputStream();
@Override
public void close() throws IOException {
int exitCode = channel.close();
logger.debug( "cat exited with {}", exitCode );
}
@Override
public void write( int b ) throws IOException {
outputStream.write( b );
}
};
}