channelsftp的put_JSch - Java实现的SFTP(文件上传详解篇)

public void put(String src, String dst)

将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同。

采用默认的传输模式:OVERWRITE

public void put(String src, String dst, int mode)

将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同。

指定文件传输模式为mode(mode可选值为:ChannelSftp.OVERWRITE,ChannelSftp.RESUME,

ChannelSftp.APPEND)

public void put(String src, String dst, SftpProgressMonitor monitor)

将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同。

采用默认的传输模式:OVERWRITE

并使用实现了SftpProgressMonitor接口的monitor对象来监控文件传输的进度。

public void put(String src, String dst,

SftpProgressMonitor monitor, int mode)

将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同。

指定传输模式为mode

并使用实现了SftpProgressMonitor接口的monitor对象来监控文件传输的进度。

public void put(InputStream src, String dst)

将本地的input stream对象src上传到目标服务器,目标文件名为dst,dst不能为目录。

采用默认的传输模式:OVERWRITE

public void put(InputStream src, String dst, int mode)

将本地的input stream对象src上传到目标服务器,目标文件名为dst,dst不能为目录。

指定文件传输模式为mode

public void put(InputStream src, String dst, SftpProgressMonitor monitor)

将本地的input stream对象src上传到目标服务器,目标文件名为dst,dst不能为目录。

采用默认的传输模式:OVERWRITE

并使用实现了SftpProgressMonitor接口的monitor对象来监控传输的进度。

public void put(InputStream src, String dst,

SftpProgressMonitor monitor, int mode)

将本地的input stream对象src上传到目标服务器,目标文件名为dst,dst不能为目录。

指定文件传输模式为mode

并使用实现了SftpProgressMonitor接口的monitor对象来监控传输的进度。

public OutputStream put(String dst)

该方法返回一个输出流,可以向该输出流中写入数据,最终将数据传输到目标服务器,目标文件名为dst,dst不能为目录。

采用默认的传输模式:OVERWRITE

public OutputStream put(String dst, final int mode)

该方法返回一个输出流,可以向该输出流中写入数据,最终将数据传输到目标服务器,目标文件名为dst,dst不能为目录。

指定文件传输模式为mode

public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode)

该方法返回一个输出流,可以向该输出流中写入数据,最终将数据传输到目标服务器,目标文件名为dst,dst不能为目录。

指定文件传输模式为mode

并使用实现了SftpProgressMonitor接口的monitor对象来监控传输的进度。

public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode, long offset)

该方法返回一个输出流,可以向该输出流中写入数据,最终将数据传输到目标服务器,目标文件名为dst,dst不能为目录。

指定文件传输模式为mode

并使用实现了SftpProgressMonitor接口的monitor对象来监控传输的进度。

offset指定了一个偏移量,从输出流偏移offset开始写入数据。

应用实例:

SFTPTest.java

SFTPTest.java

packagecom.longyg.sftp;importjava.util.HashMap;importjava.util.Map;importcom.jcraft.jsch.ChannelSftp;public classSFTPTest {publicSFTPChannel getSFTPChannel() {return newSFTPChannel();

}/***@paramargs

*@throwsException*/

public static void main(String[] args) throwsException {

SFTPTest test= newSFTPTest();

Map sftpDetails = new HashMap();//设置主机ip,端口,用户名,密码

sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, "10.9.167.55");

sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME,"root");

sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD,"arthur");

sftpDetails.put(SFTPConstants.SFTP_REQ_PORT,"22");

String src= "D:\\DevSoft\\HB-SnagIt1001.rar"; //本地文件名

String dst = "/home/omc/ylong/sftp/HB-SnagIt1001.rar"; //目标文件名

SFTPChannel channel=test.getSFTPChannel();

ChannelSftp chSftp= channel.getChannel(sftpDetails, 60000);/*** 代码段1

OutputStream out = chSftp.put(dst, ChannelSftp.OVERWRITE); // 使用OVERWRITE模式

byte[] buff = new byte[1024 * 256]; // 设定每次传输的数据块大小为256KB

int read;

if (out != null) {

System.out.println("Start to read input stream");

InputStream is = new FileInputStream(src);

do {

read = is.read(buff, 0, buff.length);

if (read > 0) {

out.write(buff, 0, read);

}

out.flush();

} while (read >= 0);

System.out.println("input stream read done.");

}

**/chSftp.put(src, dst, ChannelSftp.OVERWRITE);//代码段2//chSftp.put(new FileInputStream(src), dst, ChannelSftp.OVERWRITE);//代码段3

chSftp.quit();

channel.closeChannel();

}

}

注:请分别将代码段1,代码段2,代码段3取消注释,运行程序来进行测试。这三段代码分别演示了如何使用JSch的不同的put方法来进行文件上传。

代码段1:采用向put方法返回的输出流中写入数据的方式来传输文件。 需要由程序来决定写入什么样的数据,这里是将本地文件的输入流写入输出流。采用这种方式的好处是,可以自行设定每次写入输出流的数据块大小,如本示例中的语句:

byte[] buff = new byte[1024 * 256]; //设定每次传输的数据块大小为256KB

代码段2:直接将本地文件名为src的文件上传到目标服务器,目标文件名为dst。(注:使用这个方法时,dst可以是目录,当dst是目录时,上传后的目标文件名将与src文件名相同)

代码段3:将本地文件名为src的文件输入流上传到目标服务器,目标文件名为dst。

这三段代码实现的功能是一样的,都是将本地的文件src上传到了服务器的dst文件。使用时可根据具体情况选择使用哪种实现方式。

监控传输进度

从前面的介绍中知道,JSch支持在文件传输时对传输进度的监控。可以实现JSch提供的SftpProgressMonitor接口来完成这个功能。

SftpProgressMonitor接口类的定义为:

SftpProgressMonitor.java

packagecom.jcraft.jsch;public interfaceSftpProgressMonitor{public static final int PUT=0;public static final int GET=1;void init(int op, String src, String dest, longmax);boolean count(longcount);voidend();

}

init():当文件开始传输时,调用init方法。

count(): 当每次传输了一个数据块后,调用count方法,count方法的参数为这一次传输的数据块大小。

end():当传输结束时,调用end方法。

下面是一个简单的实现:

MyProgressMonitor.java

MyProgressMonitor.java

packagecom.longyg.sftp;importcom.jcraft.jsch.SftpProgressMonitor;public class MyProgressMonitor implementsSftpProgressMonitor {private longtransfered;

@Overridepublic boolean count(longcount) {

transfered= transfered +count;

System.out.println("Currently transferred total size: " + transfered + " bytes");return true;

}

@Overridepublic voidend() {

System.out.println("Transferring done.");

}

@Overridepublic void init(int op, String src, String dest, longmax) {

System.out.println("Transferring begin.");

}

}

此时如果改变SFTPTest main方法里调用的put方法,即可实现监控传输进度:

SFTPTest.java

SFTPTest.java

packagecom.longyg.sftp;importjava.util.HashMap;importjava.util.Map;importcom.jcraft.jsch.ChannelSftp;public classSFTPTest {publicSFTPChannel getSFTPChannel() {return newSFTPChannel();

}/***@paramargs

*@throwsException*/

public static void main(String[] args) throwsException {

SFTPTest test= newSFTPTest();

Map sftpDetails = new HashMap();//设置主机ip,端口,用户名,密码

sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, "10.9.167.55");

sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME,"root");

sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD,"arthur");

sftpDetails.put(SFTPConstants.SFTP_REQ_PORT,"22");

String src= "D:\\DevSoft\\HB-SnagIt1001.rar"; //本地文件名

String dst = "/home/omc/ylong/sftp/HB-SnagIt1001.rar"; //目标文件名

SFTPChannel channel=test.getSFTPChannel();

ChannelSftp chSftp= channel.getChannel(sftpDetails, 60000);/*** 代码段1

OutputStream out = chSftp.put(dst, new MyProgressMonitor(), ChannelSftp.OVERWRITE); // 使用OVERWRITE模式

byte[] buff = new byte[1024 * 256]; // 设定每次传输的数据块大小为256KB

int read;

if (out != null) {

System.out.println("Start to read input stream");

InputStream is = new FileInputStream(src);

do {

read = is.read(buff, 0, buff.length);

if (read > 0) {

out.write(buff, 0, read);

}

out.flush();

} while (read >= 0);

System.out.println("input stream read done.");

}

**/chSftp.put(src, dst,new MyProgressMonitor(), ChannelSftp.OVERWRITE); //代码段2//chSftp.put(new FileInputStream(src), dst, new MyProgressMonitor(), ChannelSftp.OVERWRITE);//代码段3

chSftp.quit();

channel.closeChannel();

}

}

注意修改的内容仅仅是put方法,在put方法中增加了SftpProgressMonitor的实现类对象monitor作为参数,即添加了对进度监控的支持。

运行,输出结果如下:

logs

Start to read input stream

Currently transferred total size:262144bytes

Currently transferred total size:524288bytes

Currently transferred total size:786432bytes

Currently transferred total size:1048576bytes

Currently transferred total size:1310720bytes

Currently transferred total size:1572864bytes

Currently transferred total size:1835008bytes

Currently transferred total size:2097152bytes

Currently transferred total size:2359296bytes

Currently transferred total size:2621440bytes

Currently transferred total size:2883584bytes

Currently transferred total size:3145728bytes

Currently transferred total size:3407872bytes

Currently transferred total size:3670016bytes

Currently transferred total size:3848374bytes

input stream read done.

当然这个SftpProgressMonitor的实现实在太简单。JSch每次传输一个数据块,就会调用count方法来实现主动进度通知。

现在我们希望每间隔一定的时间才获取一下文件传输的进度。。。看看下面的SftpProgressMonitor实现:

FileProgressMonitor.java

packagecom.longyg.sftp;importjava.text.DecimalFormat;importjava.util.Timer;importjava.util.TimerTask;importcom.jcraft.jsch.SftpProgressMonitor;public class FileProgressMonitor extends TimerTask implementsSftpProgressMonitor {private long progressInterval = 5 * 1000; //默认间隔时间为5秒

private boolean isEnd = false; //记录传输是否结束

private long transfered; //记录已传输的数据总大小

private long fileSize; //记录文件总大小

private Timer timer; //定时器对象

private boolean isScheduled = false; //记录是否已启动timer记时器

public FileProgressMonitor(longfileSize) {this.fileSize =fileSize;

}

@Overridepublic voidrun() {if (!isEnd()) { //判断传输是否已结束

System.out.println("Transfering is in progress.");long transfered =getTransfered();if (transfered != fileSize) { //判断当前已传输数据大小是否等于文件总大小

System.out.println("Current transfered: " + transfered + " bytes");

sendProgressMessage(transfered);

}else{

System.out.println("File transfering is done.");

setEnd(true); //如果当前已传输数据大小等于文件总大小,说明已完成,设置end

}

}else{

System.out.println("Transfering done. Cancel timer.");

stop();//如果传输结束,停止timer记时器

return;

}

}public voidstop() {

System.out.println("Try to stop progress monitor.");if (timer != null) {

timer.cancel();

timer.purge();

timer= null;

isScheduled= false;

}

System.out.println("Progress monitor stoped.");

}public voidstart() {

System.out.println("Try to start progress monitor.");if (timer == null) {

timer= newTimer();

}

timer.schedule(this, 1000, progressInterval);

isScheduled= true;

System.out.println("Progress monitor started.");

}/*** 打印progress信息

*@paramtransfered*/

private void sendProgressMessage(longtransfered) {if (fileSize != 0) {double d = ((double)transfered * 100)/(double)fileSize;

DecimalFormat df= new DecimalFormat( "#.##");

System.out.println("Sending progress message: " + df.format(d) + "%");

}else{

System.out.println("Sending progress message: " +transfered);

}

}/*** 实现了SftpProgressMonitor接口的count方法*/

public boolean count(longcount) {if (isEnd()) return false;if (!isScheduled) {

start();

}

add(count);return true;

}/*** 实现了SftpProgressMonitor接口的end方法*/

public voidend() {

setEnd(true);

System.out.println("transfering end.");

}private synchronized void add(longcount) {

transfered= transfered +count;

}private synchronized longgetTransfered() {returntransfered;

}public synchronized void setTransfered(longtransfered) {this.transfered =transfered;

}private synchronized void setEnd(booleanisEnd) {this.isEnd =isEnd;

}private synchronized booleanisEnd() {returnisEnd;

}public void init(int op, String src, String dest, longmax) {//Not used for putting InputStream

}

}

再次修改SFTPTest main方法里的put方法,改为使用新的SftpProgressMonitor的实现类对象monitor作为参数,注意新的monitor对象的构造函数需要传入文件大小作为参数:

SFTPTest.java

packagecom.longyg.sftp;importjava.io.File;importjava.util.HashMap;importjava.util.Map;importcom.jcraft.jsch.ChannelSftp;public classSFTPTest {publicSFTPChannel getSFTPChannel() {return newSFTPChannel();

}/***@paramargs

*@throwsException*/

public static void main(String[] args) throwsException {

SFTPTest test= newSFTPTest();

Map sftpDetails = new HashMap();//设置主机ip,端口,用户名,密码

sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, "10.9.167.55");

sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME,"root");

sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD,"arthur");

sftpDetails.put(SFTPConstants.SFTP_REQ_PORT,"22");

String src= "D:\\DevSoft\\HB-SnagIt1001.rar"; //本地文件名

String dst = "/home/omc/ylong/sftp/HB-SnagIt1001.rar"; //目标文件名

SFTPChannel channel=test.getSFTPChannel();

ChannelSftp chSftp= channel.getChannel(sftpDetails, 60000);

File file= newFile(src);long fileSize =file.length();/*** 代码段1

OutputStream out = chSftp.put(dst, new FileProgressMonitor(fileSize), ChannelSftp.OVERWRITE); // 使用OVERWRITE模式

byte[] buff = new byte[1024 * 256]; // 设定每次传输的数据块大小为256KB

int read;

if (out != null) {

System.out.println("Start to read input stream");

InputStream is = new FileInputStream(src);

do {

read = is.read(buff, 0, buff.length);

if (read > 0) {

out.write(buff, 0, read);

}

out.flush();

} while (read >= 0);

System.out.println("input stream read done.");

}

**/chSftp.put(src, dst,new FileProgressMonitor(fileSize), ChannelSftp.OVERWRITE); //代码段2//chSftp.put(new FileInputStream(src), dst, new FileProgressMonitor(fileSize), ChannelSftp.OVERWRITE);//代码段3

chSftp.quit();

channel.closeChannel();

}

}

再次运行,结果输出为:

logs

Try to start progress monitor.

Progress monitor started.

Transfering is in progress.

Current transfered: 98019 bytes

Sending progress message: 2.55%

Transfering is in progress.

Current transfered: 751479 bytes

Sending progress message: 19.53%

Transfering is in progress.

Current transfered: 1078209 bytes

Sending progress message: 28.02%

......

Transfering is in progress.

Current transfered: 3430665 bytes

Sending progress message: 89.15%

transfering end.

Transfering done. Cancel timer.

Try to stop progress monitor.

Progress monitor stoped.

现在,程序每隔5秒钟才会打印一下进度信息。可以修改FileProgressMonitor类里的progressInterval变量的值,来修改默认的间隔时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/566720.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

支持多达70余种嵌入式核心的嵌入式仿真软件SkyEye

SkyEye 介绍 SkyEye,中文全称天目全数字实时仿真软件,应用软件仿真技术,逼真地模拟出被测软件的物理环境。用图形化方式构建虚拟目标系统,有效降低了硬件工程师和软件工程师之间的沟通成本,软件工程师可以不依赖硬件工…

xxljob默认登录_xxl-job安装部署整理

xxl-job github源码地址:https://github.com/xuxueli/xxl-jobxxl-job 官方文档:https://www.xuxueli.com/xxl-job/#系统组成调度模块(调度中心):负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系…

嵌入式仿真平台SkyEye的覆盖率分析

随着嵌入式系统也越来越复杂,功能迭代越来越多,代码中就可能就会存在部分无用代码,或者在执行过程中无法测试覆盖的分支,这可能就会给软件带来很大的漏洞,严重降低软件的可靠性。因此,需要一个能够动态分析…

access重复数据累计_小程序·云开发之数据库自动备份丨云开发101

小程序云开发之数据库自动备份数据是无价的,我们通常会把重要的业务数据存放在数据库中,并需要对数据库做定时的自动备份工作,防止数据异常丢失,造成无法挽回的损失。小程序云开发提供了方便的云数据库供我们直接使用,…

嵌入式系统实时仿真解决方案SkyEye

SkyEye介绍 SkyEye,中文全称天目全数字实时仿真软件,应用软件仿真技术,逼真地模拟出被测软件的物理环境。用图形化方式构建虚拟目标系统,有效降低了硬件工程师和软件工程师之间的沟通成本,软件工程师可以不依赖硬件工…

read函数头文件 window_of_property_read_string 剖析

前言今天在一个群里面看到的一个朋友提交,说of_property_read_string 这个函数有两个定义,到底是用了哪个呢?所以这篇文章就说下这个函数。函数引用的头文件引用的头文件位置在kernel-4.4includelinuxof.h其中一个是extern int of_property_r…

全数字实时仿真平台SkyEye的同步数据流语言可信编译器的构造

随着计算机控制系统在人们生活中的普及,软件自身的可靠性也越来越受到重视.在航空、高铁、核电及军事等高安全要求领域的软件系统——安全关键系统(safety-critical system,简称SCS)更是受到高度的重视.而随着软件系统的复杂度越来越高,软件系统的安全性保证也变得越来越困难.这…

div html 下边加横线_HTML的组成部分、DIV+CSS布局

HTML的组成部分dtd部分:文档类型说明,声明版本、标准header部分:给机器看的body部分:给人看的CSS控制div显示是一个块级元素。这意味着它的内容自动地开始一个新行。实际上,换行是 固有的唯一格式表现。可以通过 的 cl…

国产主可控的嵌入式仿真测试软件SkyEye与可信编译器L2C的核心翻译介绍

为了满足国内某安全攸关领域的需求, L2C编译器的开发始于2010年9月, 其目标是设计实现一个经过形式化验证的可信编译器, 其源语言是面向领域的同步数据流语言Lustre*(Lustre语言的一个变种, 参考下一节), 目标语言是C, 最终可用作相关领域数字化仪控系统的安全级代码生成器.国产…

python 经纬度计算距离公式_SymPy符号计算-让Python帮我们推公式

作者: 阿凯Email: xingshunkaiqq.com概要像我这种粗心的小孩, 在推导一些复杂的公式(尤其是矩阵运算)的时候, 经常容易算错数, 一步推错,步步错。万能的Python有什么方法可以帮助我们节省时间, 减少出错率呢? 有一个包叫做SymPy, 它可以帮我们自动的进行符号化计算…

支持国产处理器仿真的全数字实时仿真平台SkyEye与可信编译器L2C的核心翻译步骤

1、核心翻译步骤示例 本节我们以第2节提到的Lustre语言的主要特性为线索来解释L2C在翻译过程中的关键节点是如何处理的, 并以图 1的实例来解释Lustre程序是如何被一步步地翻译到Clight语言的. 1.1 数据流并发性 Lustre程序具有数据流并发性, 而Clight程序却是串行执行的.因此…

python导入不在同一路径的函数_Python小课堂|模块

Python3 模块在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的…

全数字实时仿真软件SkyEye与可信编译器L2C的核心翻译步骤的设计与实现

有关翻译正确性验证的重点疑难问题及其设计实现方案 在L2C可信编译器的设计与实现中, 对于实线所对应的翻译过程 (CompCert编译器除外) 均借助于Coq证明了正确性 (语义保持性), 然后得出LustreSGen所产生的LustreS代码到Clight代码整个翻译过程的正确性.从LustreS到Clight的任…

idea 分支管理插件_Git的分支管理常用命令

文章目录分支管理git stashgitmerge与git rebasegit merge --squashcherry-pick分支管理命令作用git branch查看当前分支git checkout/git switch 分支名称切换分支git merge 分支名称将指定分支合并到当前分支git branch -d 分支名称删除指定分支git diff 分支名称1 分支名称2…

安卓蓝牙键盘切换输入法_采用国产机械轴,三种连接模式轻松切换,TT G521上手体验...

之前我用过三模游戏鼠标,也用过三模薄膜键盘,但是三模机械键盘,还是第一次使用。机械键盘,相信大家都知道,现在已经很普及了,估计当时把机械键盘重新带回到玩家当中的大神,也没有想到它会这么火…

国产自主可控的嵌入式仿真软件SkyEye和同步数据流语言高阶运算消去的可信翻译

同步数据流语言高阶运算消去的可信翻译 同步数据流语言(例如Lustre,Signal等)广泛应用于工业界的核心安全级控制系统,如航空、核电等高安全等级的关键领域,与语言相关的软件的安全性也越来越受到人们的关注,特别是一些基础软件,如操作系统、编译器等.确认这些软件的安全可靠非…

pq 中m函数判断嵌套_压轴题的热点,二次函数与几何的结合,谁会谁吃香

对于整个中考数学来说,二次函数的重要性,我想不用老师多说,大家肯定心里有数。二次函数作为初中数学的重要内容,命题老师很喜欢把它与其他几何图形进行结合,形成综合性更强的试题。不可否认,二次函数与几何…

完全自主可控的安全关键领域仿真测试软件SkyEye可替代SCADE

基于全数字实时仿真平台 SkyEye 产品性质 :全数字实时仿真平台(软件测试和仿真工具) 对标产品 :美国风河公司的Simics,可替代SCADE SkyEye,中文全称天目全数字实时仿真软件,是基于可视化建模…

请求接受json tp5_关于jq jsonp跨域请求错误处理bug

前言:昨天,同事修改项目升级插件时遇到了一个ajax 报错,如下:$.ajax({type : "get",async:false,timeout:3000,url : "http://10.10.10.26:808/servlet/updateLog?line1",dataType : "jsonp",//数…

ModelCoder国产化解决方案已逐步代替国外软件Matlab/Simulink

ModelCoder介绍 在安全关键领域,基于模型的软件工程或者软件开发已逐渐进入了我国的装备研制过程中。使用Simulink或者SCADE等嵌入式软件建模工具对算法或者控制逻辑进行可视化建模,然后生成高可靠的二进制代码逐渐成为了安全关键领域的主流开发方式。 …