保定市做网站wordpress评论框制作
web/
2025/10/8 7:06:09/
文章来源:
保定市做网站,wordpress评论框制作,网站开发合同缺陷,单人给一个公司做网站费用背景
因项目需要#xff0c;我们服务每天都需要通过SFTP协议来对接上下游进行文件传输#xff0c;但是对于一些大文件#xff0c;在与第三方公司的服务器对接过程中很可能会因为网络问题或上下游服务器性能问题导致文件上传或者下载被中断#xff0c;每次重试都需要重新对…背景
因项目需要我们服务每天都需要通过SFTP协议来对接上下游进行文件传输但是对于一些大文件在与第三方公司的服务器对接过程中很可能会因为网络问题或上下游服务器性能问题导致文件上传或者下载被中断每次重试都需要重新对文件进行上传和下载非常浪费带宽、服务器资源和时间因此我们需要尽量提升文件传输效率减少不必要的文件传输损耗。
解决思路
我们平时用一些下载软件都有个断点续传功能可以基于上一次已经传输的偏移量进行传输不需要重复传输已经传输完整的数据大大节省文件下载或者文件上传时间。
在通过SFTP进行文件传输同样可以利用该原理进行断点续传。
文件上传原理
上传文件时你首先需要与SFTP服务器建立一个安全会话Session。这需要提供用户名、密码、SFTP服务器的地址及端口。一旦会话建立就可以打开一个SFTP通道Channel进行文件传输。
在处理大文件时为了防止因网络问题导致的文件传输中断以及减少不必要的重复传输我们通常会采用断点续传的方式。这意味着如果文件传输在中途中断下一次传输可以从上次结束的地方开始而不是重新开始。
JSch库的put方法支持断点续传。通过检查远程文件的大小你可以确定已经上传的数据量。然后使用FileInputStream来打开本地文件并使用skip方法跳过已上传的部分。最后使用put方法的RESUME标志从上次中断的地方开始上传剩余的文件部分。
这种方法的好处是
节省时间不需要重新上传已经传输过的部分。减少资源消耗减少网络带宽的使用特别是在网络不稳定或计费昂贵的环境中。提高可靠性即使在传输过程中发生中断也可以保证最终文件的完整性。
文件下载原理
下载文件的原理与上传类似。同样需要建立会话和打开SFTP通道。使用get方法从SFTP服务器下载文件。如果你需要实现断点续传下载你需要检查本地文件的大小以此来确定已经下载的数据量。
如果本地文件的大小小于远程文件的大小说明下载尚未完成你可以从本地文件的末尾开始继续下载。JSch的get方法同样支持RESUME标志允许你指定从远程文件的某个位置开始下载。
断点续传下载的好处包括
节省时间如果下载被中断可以继续从中断点开始而不是从头开始。减少资源消耗只下载尚未接收的文件部分节约网络带宽。提高可靠性保证即使在网络不稳定情况下也可以最终获取完整文件。
代码实现
这里使用了com.github.mwiede的Jsch版本是基于Jcraft 0.1.55增加了一些新算法的支持。
dependencygroupIdcom.github.mwiede/groupIdartifactIdjsch/artifactIdversion0.2.16/version
/dependency文件上传断点续传实现
加入SftpProgressMonitor可以更好监控文件传输的进度
package com.eshare.resumablesftp;import com.jcraft.jsch.*;import java.io.*;public class SFTPResumeUpload {private static final int PORT 22;public static void main(String[] args) {String user parallels;String passwd xxx;String host 192.168.50.33;String localFilePath /Users/evan/Downloads/1080p.mp4;String remoteFilePath /tmp/evan/test10.mp4;try {// 设置JSchJSch jsch new JSch();Session session jsch.getSession(user, host, PORT);session.setPassword(passwd);// 设置配置信息java.util.Properties config new java.util.Properties();config.put(StrictHostKeyChecking, no);session.setConfig(config);// 连接到服务器session.connect();// 打开SFTP通道Channel channel session.openChannel(sftp);channel.connect();ChannelSftp sftpChannel (ChannelSftp) channel;long remoteSize 0;// 检查远程文件是否存在SftpATTRS attrs sftpChannel.lstat(remoteFilePath);if (!attrs.isReg()) {throw new FileNotFoundException(Remote file does not exist: remoteFilePath);}// 检查远程文件大小remoteSize attrs.getSize();// 打开本地文件RandomAccessFile raf new RandomAccessFile(localFilePath, r);// 计算从哪里开始上传long startPos Math.max(0, remoteSize);raf.seek(startPos);// 文件上传long totalBytes raf.length();OutputStream os sftpChannel.put(remoteFilePath, new MyProgressMonitor(totalBytes - remoteSize), ChannelSftp.RESUME);byte[] buffer new byte[1024 * 1024];//1Mint bytesRead;while ((bytesRead raf.read(buffer)) ! -1) {os.write(buffer, 0, bytesRead);}os.close();raf.close();// 检查文件传输是否已经完成ÒÒif (sftpChannel.lstat(remoteFilePath).getSize() totalBytes) {System.out.println(File upload completed successfully.);} else {System.out.println(File upload failed.);}// 关闭连接sftpChannel.exit();session.disconnect();} catch (JSchException | IOException | SftpException e) {e.printStackTrace();}}public static class MyProgressMonitor implements SftpProgressMonitor {private long totalBytes;private long transferredBytes 0;public MyProgressMonitor(long totalBytes) {this.totalBytes totalBytes;}Overridepublic void init(int op, String src, String dest, long max) {System.out.println(Starting transfer: src -- dest);}Overridepublic boolean count(long bytes) {transferredBytes bytes;double percentage (double) transferredBytes / totalBytes * 100;System.out.printf(Transferred %d of %d bytes (%.2f%%)\n, transferredBytes, totalBytes, percentage);return true;}Overridepublic void end() {System.out.println(\nTransfer complete.);}}}断点续传测试步骤
1.我本地放一个2.1G的测试文件
2.准备好远程目录这里提前创建好一个测试目录在远程虚拟机/tmp/evan 3.启动程序控制台会打印文件传输进度文件传输到52%左右我把程序直接杀死来模拟网络中断或者传输中断的情况 4.重新启动程序让程序自动从上一次传输的偏移量继续上传大家可以尝试多次中断来模拟。 5.文件传输完成后到远程目录对比文件大小这里也可以通过文件checksum来进行对比以下输出结果可以看到文件被成功上传。 文件下载断点续传实现
package com.eshare.resumablesftp;import com.jcraft.jsch.*;import java.io.*;
import java.math.BigInteger;
import java.nio.file.*;
import java.security.MessageDigest;public class SFTPResumeDownload {private static final int PORT 22;public static void main(String[] args) {String user parallels;String passwd xxx;String host 192.168.50.33;String localFilePath /Users/evan/Downloads/test10.mp4;String remoteFilePath /tmp/evan/test10.mp4;try {// 设置JSchJSch jsch new JSch();Session session jsch.getSession(user, host, PORT);session.setPassword(passwd);// 设置配置信息java.util.Properties config new java.util.Properties();config.put(StrictHostKeyChecking, no);session.setConfig(config);// 连接到服务器session.connect();// 打开SFTP通道Channel channel session.openChannel(sftp);channel.connect();ChannelSftp sftpChannel (ChannelSftp) channel;// 检查远程文件是否存在SftpATTRS attrs null;try {attrs sftpChannel.lstat(remoteFilePath);} catch (SftpException e) {if (e.id ChannelSftp.SSH_FX_NO_SUCH_FILE) {throw new FileNotFoundException(Remote file does not exist: remoteFilePath);}throw e;}// 检查本地文件大小long localSize new File(localFilePath).length();// 打开远程文件long remoteSize attrs.getSize();// 检查文件是否正常if (localSize remoteSize) {throw new FileSystemAlreadyExistsException(Local file exists and please check the size: remoteFilePath);}/// 计算从哪里开始下载long startPos Math.max(0, localSize);// 文件下载FileOutputStream fos new FileOutputStream(localFilePath, true);InputStream is sftpChannel.get(remoteFilePath, new MyProgressMonitor(remoteSize - startPos), startPos);byte[] buffer new byte[1024 * 1024];//1Mint bytesRead;while ((bytesRead is.read(buffer)) ! -1) {fos.write(buffer, 0, bytesRead);}is.close();fos.close();// 检查文件下载是否已经完成if (new File(localFilePath).length() remoteSize) {System.out.println(File download completed successfully.);} else {System.out.println(File download failed.);}// 关闭连接sftpChannel.exit();session.disconnect();} catch (JSchException | IOException | SftpException e) {e.printStackTrace();}}public static class MyProgressMonitor implements SftpProgressMonitor {private long totalBytes;private long transferredBytes 0;public MyProgressMonitor(long totalBytes) {this.totalBytes totalBytes;}Overridepublic void init(int op, String src, String dest, long max) {System.out.println(Starting transfer: src -- dest);}Overridepublic boolean count(long bytes) {transferredBytes bytes;double percentage (double) transferredBytes / totalBytes * 100;System.out.printf(Downloaded %d of %d bytes (%.2f%%)\n, transferredBytes, totalBytes, percentage);return true;}Overridepublic void end() {System.out.println(\nTransfer complete.);}}
}
断点续传测试步骤
1.我远程放一个2.1G的测试文件
parallelsubuntu-linux-22-04-desktop:/tmp/evan$ ls -lh test10.mp4
-rw-rw-r-- 1 parallels parallels 2.1G Jan 23 11:15 test10.mp42.准备好本地目录这里是我本机下载目录/Users/evan/Downloads/ 3.启动程序控制台会打印文件传输进度文件传输到86%左右我把程序直接杀死来模拟网络中断或者传输中断的情况 4.重新启动程序让程序自动从上一次传输的偏移量继续上传大家可以尝试多次中断来模拟。 5.文件传输完成后到远程目录对比文件大小这里也可以通过文件checksum来进行对比以下输出结果可以看到文件被成功上传。
evanEvandeMBP Downloads % ls -lh test10.mp4
-rw-r--r-- 1 evan staff 2.1G Jan 23 14:39 test10.mp4
evanEvandeMBP Downloads %
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/88928.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!