📄 channelsftp.cs
字号:
offset+=skip;
}
while(true)
{
//i=src.read(data, 0, data.Length);
i=0;
int nread=0;
do
{
nread=src.Read(data, i, data.Length-i);
if(nread>0)
{
i+=nread;
}
}
while(i<data.Length && nread>0);
if(i<=0)break;
sendWRITE(handle, offset, data, 0, i);
offset+=i;
if(!checkStatus()){ break; }
if(monitor!=null && !monitor.count(i))
{
break;
}
}
if(monitor!=null)monitor.end();
_sendCLOSE(handle);
}
catch(Exception e)
{
if(e is SftpException) throw (SftpException)e;
throw new SftpException(SSH_FX_FAILURE, "");
}
}
/**/
public Stream put(String dst)
{
return put(dst, (SftpProgressMonitor)null, OVERWRITE);
}
public Stream put(String dst, int mode)
{
return put(dst, (SftpProgressMonitor)null, mode);
}
public Stream put(String dst, SftpProgressMonitor monitor, int mode)
{
if(!dst.StartsWith("/")){ dst=cwd+"/"+dst; }
try
{
ArrayList v=glob_remote(dst);
if(v.Count!=1)
{
throw new SftpException(SSH_FX_FAILURE, v.ToString());
}
dst=(String)(v[0]);
if(isRemoteDir(dst))
{
throw new SftpException(SSH_FX_FAILURE, dst+" is a directory");
}
long skip=0;
if(mode==RESUME || mode==APPEND)
{
try
{
SftpATTRS attr=stat(dst);
skip=attr.getSize();
}
catch(Exception eee)
{
//System.out.println(eee);
}
}
if(mode==OVERWRITE){ sendOPENW(Util.getBytes(dst)); }
else{ sendOPENA(Util.getBytes(dst)); }
buf.rewind();
int i=io.ins.Read(buf.buffer, 0, buf.buffer.Length);
int length=buf.getInt();
int type=buf.getByte();
if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE)
{
throw new SftpException(SSH_FX_FAILURE, "");
}
if(type==SSH_FXP_STATUS)
{
buf.getInt();
i=buf.getInt();
throwStatusError(buf, i);
}
buf.getInt();
byte[] handle=buf.getString(); // filename
long offset=0;
if(mode==RESUME || mode==APPEND)
{
offset+=skip;
}
long[] _offset=new long[1];
_offset[0]=offset;
OutputStreamPut outs = new OutputStreamPut
(this,handle,_offset,monitor);
return outs;
}
catch(Exception e)
{
if(e is SftpException) throw (SftpException)e;
throw new SftpException(SSH_FX_FAILURE, "");
}
}
internal class OutputStreamPut : java.io.OutputStream
{
ChannelSftp sftp;
byte[] handle;
long[] _offset;
SftpProgressMonitor monitor;
internal OutputStreamPut
(ChannelSftp sftp,
byte[] handle,
long[] _offset,
SftpProgressMonitor monitor):base()
{
this.sftp=sftp;
this.handle=handle;
this._offset=_offset;
this.monitor=monitor;
}
public override void Write(byte[] d, int s, int len)
{
try
{
sftp.sendWRITE(handle, _offset[0], d, s, len);
_offset[0]+=len;
if(!sftp.checkStatus())
{
throw new IOException("jsch status error");
}
if(monitor!=null && !monitor.count(1))
{
throw new IOException("canceled");
}
}
catch(IOException e){ throw e; }
catch(Exception e){ throw new IOException(e.ToString()); }
}
byte[] _data=new byte[1];
public override void WriteByte(byte foo)
{
_data[0]=foo;
Write(_data, 0, 1);
}
public void Write(int foo)
{
this.WriteByte((byte)foo);
}
public override void Close()
{
if(monitor!=null)monitor.end();
try{ sftp._sendCLOSE(handle); }
catch(IOException e){ throw e; }
catch(Exception e)
{
throw new IOException(e.ToString());
}
}
}
/**/
public void get(String src, String dst)
{
get(src, dst, null, OVERWRITE);
}
public void get(String src, String dst,
SftpProgressMonitor monitor)
{
get(src, dst, monitor, OVERWRITE);
}
public void get(String src, String dst,
SftpProgressMonitor monitor, int mode)
{
if(!src.StartsWith("/")){ src=cwd+"/"+src; }
// if(!dst.StartsWith("/")){ dst=lcwd+file_separator+dst; }
if(!isLocalAbsolutePath(dst)){ dst=lcwd+file_separator+dst; }
try
{
ArrayList v=glob_remote(src);
if(v.Count==0)
{
throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such file");
}
for(int j=0; j<v.Count; j++)
{
String _dst=dst;
String _src=(String)(v[j]);
if(Directory.Exists(_dst))
{
if(!_dst.EndsWith(file_separator))
{
_dst+=file_separator;
}
int i=_src.LastIndexOf('/');
if(i==-1) _dst+=src;
else _dst+=_src.Substring(i+1);
}
SftpATTRS attr=stat(_src);
if(mode==RESUME)
{
long size_of_src=attr.getSize();
long size_of_dst=new FileInfo(_dst).Length;
if(size_of_dst>size_of_src)
{
throw new SftpException(SSH_FX_FAILURE, "failed to resume for "+_dst);
}
if(size_of_dst==size_of_src)
{
return;
}
}
if(monitor!=null)
{
monitor.init(SftpProgressMonitor.GET, _src, _dst, attr.getSize());
if(mode==RESUME)
{
monitor.count(new FileInfo(_dst).Length);
}
}
FileStream fos=null;
if(mode==OVERWRITE)
{
fos=new FileStream(_dst, FileMode.Create);
}
else
{
fos=new FileStream(_dst, FileMode.Append); // append
}
_get(_src, fos, monitor, mode, new FileInfo(_dst).Length);
fos.Close();
}
}
catch(Exception e)
{
if(e is SftpException) throw (SftpException)e;
throw new SftpException(SSH_FX_FAILURE, "");
}
}
public void get(String src, Stream dst)
{
get(src, dst, null, OVERWRITE, 0);
}
public void get(String src, Stream dst,
SftpProgressMonitor monitor)
{
get(src, dst, monitor, OVERWRITE, 0);
}
public void get(String src, Stream dst,
SftpProgressMonitor monitor, int mode, long skip)
{
//System.out.println("get: "+src+", "+dst);
try
{
if(!src.StartsWith("/")){ src=cwd+"/"+src; }
ArrayList v=glob_remote(src);
if(v.Count!=1)
{
throw new SftpException(SSH_FX_FAILURE, v.ToString());
}
src=(String)(v[0]);
if(monitor!=null)
{
SftpATTRS attr=stat(src);
monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize());
if(mode==RESUME)
{
monitor.count(skip);
}
}
_get(src, dst, monitor, mode, skip);
}
catch(Exception e)
{
if(e is SftpException) throw (SftpException)e;
throw new SftpException(SSH_FX_FAILURE, "");
}
}
private void _get(String src, Stream dst,
SftpProgressMonitor monitor, int mode, long skip)
{
//System.out.println("_get: "+src+", "+dst);
try
{
sendOPENR(Util.getBytes(src));
buf.rewind();
int i=io.ins.Read(buf.buffer, 0, buf.buffer.Length);
int length=buf.getInt();
int type=buf.getByte();
if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE)
{
throw new SftpException(SSH_FX_FAILURE, "");
}
if(type==SSH_FXP_STATUS)
{
buf.getInt();
i=buf.getInt();
throwStatusError(buf, i);
}
buf.getInt();
byte[] handle=buf.getString(); // filename
long offset=0;
if(mode==RESUME)
{
offset+=skip;
}
int request_len=0;
loop:
while(true)
{
request_len=buf.buffer.Length-13;
if(server_version==0){ request_len=1024; }
sendREAD(handle, offset, request_len);
buf.rewind();
i=io.ins.Read(buf.buffer, 0, 13); // 4 + 1 + 4 + 4
if(i!=13)
{
goto BREAK;
}
length=buf.getInt();
type=buf.getByte();
length--;
buf.getInt();
length-=4;
if(type!=SSH_FXP_STATUS && type!=SSH_FXP_DATA)
{
goto BREAK;
}
if(type==SSH_FXP_STATUS)
{
i=buf.getInt();
length-=4;
io.ins.Read(buf.buffer, 13, length);
if(i==SSH_FX_EOF)
{
goto BREAK;
}
throwStatusError(buf, i);
}
i=buf.getInt();
length-=4;
int foo=i;
while(foo>0)
{
int bar=length;
if(bar>buf.buffer.Length)
{
bar=buf.buffer.Length;
}
i=io.ins.Read(buf.buffer, 0, bar);
if(i<0)
{
goto BREAK;
}
int data_len=i;
length-=data_len;
dst.Write(buf.buffer, 0, data_len);
if(monitor!=null)
{
if(!monitor.count(data_len))
{
goto BREAK;
}
}
offset+=data_len;
foo-=data_len;
}
//System.out.println("length: "+length); // length should be 0
}
BREAK:
dst.Flush();
if(monitor!=null)monitor.end();
_sendCLOSE(handle);
}
catch(Exception e)
{
if(e is SftpException) throw (SftpException)e;
throw new SftpException(SSH_FX_FAILURE, "");
}
}
public Stream get(String src)
{
return get(src, null, OVERWRITE);
}
public Stream get(String src, SftpProgressMonitor monitor)
{
return get(src, monitor, OVERWRITE);
}
public Stream get(String src, int mode)
{
return get(src, null, mode);
}
public Stream get(String src, SftpProgressMonitor monitor, int mode)
{
if(mode==RESUME)
{
throw new SftpException(SSH_FX_FAILURE, "faile to resume from "+src);
}
if(!src.StartsWith("/")){ src=cwd+"/"+src; }
try
{
ArrayList v=glob_remote(src);
if(v.Count!=1)
{
throw new SftpException(SSH_FX_FAILURE, v.ToString());
}
src=(String)(v[0]);
SftpATTRS attr=stat(src);
if(monitor!=null)
{
monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize());
}
sendOPENR(Util.getBytes(src));
buf.rewind();
int i=io.ins.Read(buf.buffer, 0, buf.buffer.Length);
int length=buf.getInt();
int type=buf.getByte();
if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE)
{
throw new SftpException(SSH_FX_FAILURE, "");
}
if(type==SSH_FXP_STATUS)
{
buf.getInt();
i=buf.getInt();
throwStatusError(buf, i);
}
buf.getInt();
byte[] handle=buf.getString(); // filename
long[] _offset=new long[1];
//_offset[0]=0;
int[] _server_version=new int[1];
_server_version[0]=server_version;
InputStreamGet ins=new InputStreamGet(this, handle, _offset, _server_version, monitor);
return ins;
}
catch(Exception e)
{
if(e is SftpException) throw (SftpException)e;
throw new SftpException(SSH_FX_FAILURE, "");
}
}
public class InputStreamGet : java.io.InputStream
{
bool closed=false;
int rest_length=0;
byte[] _data=new byte[1];
ChannelSftp sftp;
byte[] handle;
long[] _offset;
int[]_server_version;
SftpProgressMonitor monitor;
public InputStreamGet(
ChannelSftp sftp,
byte[] handle,
long[] _offset,
int[] _server_version,
SftpProgressMonitor monitor)
{
this.sftp=sftp;
this.handle=handle;
this._offset=_offset;
this._server_version=_server_version;
this.monitor=monitor;
}
public override int ReadByte()
{
int i=Read(_data, 0, 1);
if (i==-1) { return -1; }
else
{
return _data[0]&0xff;
}
}
public int Read(byte[] d)
{
return Read(d, 0, d.Length);
}
public override int Read(byte[] d, int s, int len)
{
if(d==null){throw new NullReferenceException();}
if(s<0 || len <0 || s+len>d.Length)
{
throw new IndexOutOfRangeException();
}
if(len==0){ return 0; }
if(rest_length>0)
{
int foo=rest_length;
if(foo>len) foo=len;
int i=sftp.io.ins.Read(d, s, foo);
if(i<0)
{
throw new IOException("error");
}
rest_length-=foo;
return i;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -