当前位置: 首页 > news >正文

下载远程服务器文件

  • 业务需求:下载某云盘的视频文件存储到本地

  • 测试代码
@RequestMapping("testVideo")public String test() {try {SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd/");//组装本地保存地址StringBuilder filePath = new StringBuilder(StorePathUtil.getStorePath());// \\192.168.20.2\store\stu\upload\video\msyk\2023\08\01\EN123123JD\1filePath.append("upload").append(BaseConstant.SEPERATOR).append("video").append(BaseConstant.SEPERATOR).append("msyk").append(BaseConstant.SEPERATOR).append(DATE_FORMAT.format(new Date())).append(BaseConstant.SEPERATOR).append("asdasda").append(BaseConstant.SEPERATOR).append("1").append(BaseConstant.SEPERATOR);for (int i = 0; i < 3; i++) {//保存文件名称String fileName = "测试"+i+".mp4";SiteInfoBean bean = new SiteInfoBean("http://vjs.zencdn.net/v/oceans.mp4",filePath.toString(),fileName  , 5);//启动线程,并回调处理信息SiteFileFetch fileFetch = new SiteFileFetch(bean, result -> System.out.println("downsucc" + result));fileFetch.start();}}catch (Exception e) {e.printStackTrace();}return "succ";}

  • 主要下载类
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.function.Consumer;/*** @author user* @version $$ Revision: 1.0 $$, $$ Date: 2023-08-01 15:45 $$*/
public class SiteFileFetch extends Thread {SiteInfoBean siteInfoBean = null; // 文件信息 Beanlong[] nStartPos; // 开始位置long[] nEndPos; // 结束位置FileSplitterFetch[] fileSplitterFetch; // 子线程对象long nFileLength; // 文件长度boolean bFirst = true; // 是否第一次取文件boolean bStop = false; // 停止标志File tmpFile; // 文件下载的临时信息DataOutputStream output; // 输出到文件的输出流Consumer consumer;public SiteFileFetch(SiteInfoBean bean, Consumer consumer) throws IOException {siteInfoBean = bean;this.consumer = consumer;tmpFile = new File(bean.getSFilePath() + File.separator + bean.getSFileName() + ".info");if (tmpFile.exists()) {bFirst = false;read_nPos();}else {nStartPos = new long[bean.getNSplitter()];nEndPos = new long[bean.getNSplitter()];}}@Overridepublic void run() {// 获得文件长度// 分割文件// 实例 FileSplitterFetch// 启动 FileSplitterFetch 线程// 等待子线程返回try {if (bFirst) {nFileLength = getFileSize();if (nFileLength == -1) {System.err.println("File Length is not known!");}else if (nFileLength == -2) {System.err.println("File is not access!");}else {for (int i = 0; i < nStartPos.length; i++) {nStartPos[i] = (long) (i * (nFileLength / nStartPos.length));}for (int i = 0; i < nEndPos.length - 1; i++) {nEndPos[i] = nStartPos[i + 1];}nEndPos[nEndPos.length - 1] = nFileLength;}//判断文件夹是否存在File file = new File(siteInfoBean.getSFilePath());if (!file.exists()) {file.mkdirs();}}// 启动子线程fileSplitterFetch = new FileSplitterFetch[nStartPos.length];for (int i = 0; i < nStartPos.length; i++) {fileSplitterFetch[i] = new FileSplitterFetch(siteInfoBean.getSSiteURL(),siteInfoBean.getSFilePath() + File.separator + siteInfoBean.getSFileName(), nStartPos[i],nEndPos[i], i);Utility.log("Thread " + i + " , nStartPos = " + nStartPos[i] + ", nEndPos = " + nEndPos[i]);fileSplitterFetch[i].start();}//            fileSplitterFetch[nPos.length - 1] = new FileSplitterFetch(siteInfoBean.getSSiteURL(),//                    siteInfoBean.getSFilePath() + File.separator + siteInfoBean.getSFileName(), nPos[nPos.length - 1],//                    nFileLength, nPos.length - 1);//            Utility.log("Thread " + (nPos.length - 1) + ",nStartPos = " + nPos[nPos.length - 1] + ",nEndPos = "//                    + nFileLength);//            fileSplitterFetch[nPos.length - 1].start();// 等待子线程结束//int count = 0;// 是否结束 while 循环boolean breakWhile = false;while (!bStop) {write_nPos();Utility.sleep(500);breakWhile = true;for (int i = 0; i < nStartPos.length; i++) {if (!fileSplitterFetch[i].bDownOver) {breakWhile = false;break;}}if (breakWhile) {break;}//count++;//if(count>4)// siteStop();}System.err.println("文件下载结束!");tmpFile.delete();consumer.accept("下载地址:" + siteInfoBean.getSSiteURL() + ",保存地址:" + siteInfoBean.getSFilePath()+ siteInfoBean.getSFileName());}catch (Exception e) {e.printStackTrace();}finally {}}// 获得文件长度public long getFileSize() {int nFileLength = -1;try {URL url = new URL(siteInfoBean.getSSiteURL());HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();httpConnection.setRequestProperty("User-Agent", "NetFox");int responseCode = httpConnection.getResponseCode();if (responseCode >= 400) {processErrorCode(responseCode);return -2; //-2 represent access is error}String sHeader;for (int i = 1; ; i++) {//DataInputStream in = new DataInputStream(httpConnection.getInputStream ());//Utility.log(in.readLine());sHeader = httpConnection.getHeaderFieldKey(i);if (sHeader != null) {if (sHeader.equals("Content-Length")) {nFileLength = Integer.parseInt(httpConnection.getHeaderField(sHeader));break;}}else {break;}}}catch (Exception e) {e.printStackTrace();}Utility.log(nFileLength);return nFileLength;}// 保存下载信息(文件指针位置)private void write_nPos() {try {output = new DataOutputStream(new FileOutputStream(tmpFile));output.writeInt(nStartPos.length);for (int i = 0; i < nStartPos.length; i++) {// output.writeLong(nPos[i]);output.writeLong(fileSplitterFetch[i].nStartPos);output.writeLong(fileSplitterFetch[i].nEndPos);}output.close();}catch (Exception e) {e.printStackTrace();}}// 读取保存的下载信息(文件指针位置)private void read_nPos() {try {DataInputStream input = new DataInputStream(new FileInputStream(tmpFile));int nCount = input.readInt();nStartPos = new long[nCount];nEndPos = new long[nCount];for (int i = 0; i < nStartPos.length; i++) {nStartPos[i] = input.readLong();nEndPos[i] = input.readLong();}input.close();}catch (Exception e) {e.printStackTrace();}}private void processErrorCode(int nErrorCode) {System.err.println("Error Code : " + nErrorCode);}// 停止文件下载public void siteStop() {bStop = true;for (int i = 0; i < nStartPos.length; i++) {fileSplitterFetch[i].splitterStop();}}
}

  • 内部多线程下载类
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;public class FileSplitterFetch extends Thread {String sURL; //File URLlong nStartPos; //File Snippet Start Positionlong nEndPos; //File Snippet End Positionint nThreadID; //Thread's IDboolean bDownOver = false; //Downing is overboolean bStop = false; //Stop identicalFileAccessI fileAccessI = null; //File Access interfacepublic FileSplitterFetch(String sURL, String sName, long nStart, long nEnd, int id) throws IOException {this.sURL = sURL;this.nStartPos = nStart;this.nEndPos = nEnd;nThreadID = id;fileAccessI = new FileAccessI(sName, nStartPos);}@Overridepublic void run() {while (nStartPos < nEndPos && !bStop) {try {URL url = new URL(sURL);HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();httpConnection.setRequestProperty("User-Agent", "NetFox");String sProperty = "bytes=" + nStartPos + "-";httpConnection.setRequestProperty("RANGE", sProperty);Utility.log(sProperty);InputStream input = httpConnection.getInputStream();//logResponseHead(httpConnection);byte[] b = new byte[1024];int nRead;while ((nRead = input.read(b, 0, 1024)) > 0 && nStartPos < nEndPos && !bStop) {nStartPos += fileAccessI.write(b, 0, nRead);//if(nThreadID == 1)// Utility.log("nStartPos = " + nStartPos + ", nEndPos = " + nEndPos);}Utility.log("Thread " + nThreadID + " is over!");bDownOver = true;//nPos = fileAccessI.write (b,0,nRead);}catch (Exception e) {e.printStackTrace();}finally {try {fileAccessI.close();}catch (IOException e) {e.printStackTrace();}}}}// 打印回应的头信息public void logResponseHead(HttpURLConnection con) {for (int i = 1; ; i++) {String header = con.getHeaderFieldKey(i);if (header != null) {//responseHeaders.put(header,httpConnection.getHeaderField(header));Utility.log(header + " : " + con.getHeaderField(header));}else {break;}}}public void splitterStop() {bStop = true;}
}

  • 实体类
public class SiteInfoBean {private String sSiteURL; //Site's URLprivate String sFilePath; //Saved File's Pathprivate String sFileName; //Saved File's Nameprivate int nSplitter; //Count of Splited Downloading Filepublic SiteInfoBean(){//default value of nSplitter is 5this("","","",5);}public SiteInfoBean(String sURL,String sPath,String sName,int nSpiltter){sSiteURL= sURL;sFilePath = sPath;sFileName = sName;this.nSplitter = nSpiltter;}public String getSSiteURL(){return sSiteURL;}public void setSSiteURL(String value){sSiteURL = value;}public String getSFilePath(){return sFilePath;}public void setSFilePath(String value){sFilePath = value;}public String getSFileName(){return sFileName;}public void setSFileName(String value){sFileName = value;}public int getNSplitter(){return nSplitter;}public void setNSplitter(int nCount){nSplitter = nCount;}
}
import java.io.*;class FileAccessI  implements Serializable{RandomAccessFile oSavedFile;long nPos;public FileAccessI() throws IOException {this("",0);}public FileAccessI(String sName,long nPos) throws IOException {oSavedFile = new RandomAccessFile(sName,"rw");this.nPos = nPos;oSavedFile.seek(nPos);}public synchronized int write(byte[] b,int nStart,int nLen){int n = -1;try{oSavedFile.write(b,nStart,nLen);n = nLen;}catch(IOException e){e.printStackTrace ();}return n;}void close() throws IOException {oSavedFile.close();}
}

  • 日志类
public class Utility {public Utility() {}public static void sleep(int nSecond) {try {Thread.sleep(nSecond);}catch (Exception e) {e.printStackTrace();}}public static void log(String sMsg) {System.err.println(sMsg);}public static void log(int sMsg) {System.err.println(sMsg);}
}

相关文章:

下载远程服务器文件

业务需求:下载某云盘的视频文件存储到本地 测试代码 RequestMapping("testVideo")public String test() {try {SimpleDateFormat DATE_FORMAT new SimpleDateFormat("yyyy/MM/dd/");//组装本地保存地址StringBuilder filePath new StringBuilder(StoreP…...

[SQL挖掘机] - 索引

介绍: 当你在数据库中进行查询时&#xff0c;索引是一种用于提高查询性能的重要工具。索引是对表中的一列或多列进行排序的数据结构&#xff0c;它可以快速定位到满足特定条件的记录&#xff0c;从而减少了查询所需的时间和资源。 在数据库中使用索引的主要好处包括&#xff…...

C++STL库中的list

文章目录 list的介绍及使用 list的常用接口 list的模拟实现 list与vector的对比 一、list的介绍及使用 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list的底层是双向带头循环链表结构&#xff0c;双向带头循…...

【LeetCode 75】第十七题(1493)删掉一个元素以后全为1的最长子数组

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给一个数组&#xff0c;求删除一个元素以后能得到的连续的最长的全是1的子数组。 我们可以先单独统计出连续为1的子数组分别长度…...

配置IPv6 over IPv4 GRE隧道示例

组网需求 如图1&#xff0c;两个IPv6网络分别通过SwitchA和SwitchC与IPv4公网中的SwitchB连接&#xff0c;客户希望两个IPv6网络中的PC1和PC2实现互通。 其中PC1和PC2上分别指定SwitchA和SwitchC为自己的缺省网关。 图1 配置IPv6 over IPv4 GRE隧道组网图 配置思路 要实现I…...

Google Earth Engine谷歌地球引擎提取多波段长期反射率数据后绘制折线图并导出为Excel

本文介绍在谷歌地球引擎GEE中&#xff0c;提取多年遥感影像多个不同波段的反射率数据&#xff0c;在GEE内绘制各波段的长时间序列走势曲线图&#xff0c;并将各波段的反射率数据与其对应的成像日期一起导出为.csv文件的方法。 本文是谷歌地球引擎&#xff08;Google Earth Engi…...

第三大的数

414、第三大的数 class Solution {public int thirdMax(int[] nums) {Arrays.sort(nums);int tempnums[0];int ansnums[0];int count 0;// if(nums.length<3){// return nums[nums.length-1];// }// else {for(int inums.length-1;i>0;i--){if (nums[i]>nums[i…...

正则表达式中的方括号[]有什么用?

在正则表达式中&#xff0c;方括号 [] 是用于定义字符集合的元字符。它在正则表达式中有以下作用&#xff1a; 匹配字符集合中的任意一个字符&#xff1a;方括号中列出的字符&#xff0c;表示在这个位置可以匹配这些字符中的任意一个。例如&#xff0c;[abc] 将匹配任意一个字符…...

SQL编写规范

文章目录 1.命名规范&#xff1a;2.库表设计&#xff1a;3.查询数据&#xff1a;4.修改数据&#xff1a;5.索引创建&#xff1a; 1.命名规范&#xff1a; 1.库名、表名、字段名&#xff0c;必须使用小写字母或数字&#xff0c;不得超过30个字符。 2.库名、表名、字段名&#…...

Azure pipeline自动化打包发布

pipeline自动化&#xff0c;提交代码后&#xff0c;就自动打包&#xff0c;打包成功后自动发布 第一步 pipeline提交代码后&#xff0c;自动打包。 1 在Repos,分支里选择要触发的分支&#xff0c;这里选择cn_china,对该分支设置分支策略 2 在生产验证中增加新的策略 3 在分支安…...

【算法提高:动态规划】1.4 状态机模型 TODO

文章目录 例题列表1049. 大盗阿福&#xff08;其实就是打家劫舍&#xff09;1057. 股票买卖 IV&#xff08;k笔交易&#xff09;1058. 股票买卖 V&#xff08;冷冻期&#xff09;1052. 设计密码⭐⭐⭐&#x1f6b9;&#x1f6b9;&#x1f6b9;&#xff08;TODO&#xff09;1053…...

ip link add 命令

ip link add veth0 type veth peer name veth1 这条命令主要用于在 Linux 操作系统中创建一个新的 veth(虚拟以太网) 对&#xff0c;这是一种虚拟网络设备&#xff0c;用于在 Linux 命名空间&#xff08;namespaces&#xff09;之间创建网络连接。此命令将创建两个设备&#xf…...

unity事件处理

方法调用 //发送事件 【发送事件码&#xff0c;发送消息内容】 EventCenterUtil.Broadcast(EventCenterUtil.EventType.Joystick, ui);//监听无参事件 EventCenterUtil.AddListener(EventCenterUtil.EventType.Joystick, show); public void show(){}//发送事件 有参事件 Eve…...

《ChatGPT原理最佳解释,从根上理解ChatGPT》

【热点】 2022年11月30日&#xff0c;OpenAI发布ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c; 即聊天机器人程序 &#xff0c;开启AIGC的研究热潮。 ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;它能够…...

大数据Flink(五十):流式计算简介

文章目录 流式计算简介 一、数据的时效性 二、流式计算和批量计算...

13-4_Qt 5.9 C++开发指南_基于QWaitCondition 的线程同步_Wait

在多线程的程序中&#xff0c;多个线程之间的同步实际上就是它们之间的协调问题。例如上一小节讲到的3个线程的例子中&#xff0c;假设 threadDAQ 写满一个缓冲区之后&#xff0c;threadShow 和 threadSaveFile 才能对缓冲区进行读操作。前面采用的互斥量和基于 OReadWriteLock…...

STM32(HAL)多串口进行重定向(printf函数发送数据)

目录 1、简介 2.1 基础配置 2.1.1 SYS配置 2.1.2 RCC配置 2.2 串口外设配置 2.3 项目生成 3、KEIL端程序整合 4、效果测试 1、简介 在HAL库中&#xff0c;常用的printf函数是无法使用的。本文通过重映射实现在HAL库多个串口可进行类似printf函数的操作。 2.1 基础配置 2.…...

29_互联网(The Internet)(IP数据包;UDP;TCP;DNS;OSI)

上篇介绍了计算机网络的基础知识&#xff0c;也提到互联网&#xff08;The Internet&#xff09;&#xff0c;本篇将会详细介绍互联网&#xff08;The Internet&#xff09;。 文章目录 1. 互联网&#xff08;The Internet&#xff09;组成及数据包传输过程2. IP 数据包的不足3…...

xShell常用命令

xShell常用命令 一、文件夹目录1、cd-更改目录2、mkdir-建立目录3、rm-删除目录4、pwd-查看当前路径5、rmdir-删除空目录 二、文件操作1、cat-显示文件内容2、diff-比较文件内容3、查看文件的名字和后缀4、ls-列出文件5、cp-复制文件6、mv-移动和重命名文件找不同&#xff1a;选…...

React性能优化之Memo、useMemo

文章目录 React.memo两种方式参数应用场景 拓展useMemouseMemo(calculateValue, dependencies) 参考资料 React.memo React 的渲染机制&#xff0c;组件内部的 state 或者 props 一旦发生修改&#xff0c;整个组件树都会被重新渲染一次&#xff0c;即时子组件的参数没有被修改&…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

Pydantic + Function Calling的结合

1、Pydantic Pydantic 是一个 Python 库&#xff0c;用于数据验证和设置管理&#xff0c;通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发&#xff08;如 FastAPI&#xff09;、配置管理和数据解析&#xff0c;核心功能包括&#xff1a; 数据验证&#xff1a;通过…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”

非常好&#xff0c;我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题&#xff0c;统一使用 二重复合函数&#xff1a; z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y))​ 来全面说明。我们会展示其全微分形式&#xff08;偏导…...

Python的__call__ 方法

在 Python 中&#xff0c;__call__ 是一个特殊的魔术方法&#xff08;magic method&#xff09;&#xff0c;它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时&#xff08;例如 obj()&#xff09;&#xff0c;Python 会自动调用该对象的 __call__ 方法…...

理想汽车5月交付40856辆,同比增长16.7%

6月1日&#xff0c;理想汽车官方宣布&#xff0c;5月交付新车40856辆&#xff0c;同比增长16.7%。截至2025年5月31日&#xff0c;理想汽车历史累计交付量为1301531辆。 官方表示&#xff0c;理想L系列智能焕新版在5月正式发布&#xff0c;全系产品力有显著的提升&#xff0c;每…...

开疆智能Ethernet/IP转Modbus网关连接鸣志步进电机驱动器配置案例

在工业自动化控制系统中&#xff0c;常常会遇到不同品牌和通信协议的设备需要协同工作的情况。本案例中&#xff0c;客户现场采用了 罗克韦尔PLC&#xff0c;但需要控制的变频器仅支持 ModbusRTU 协议。为了实现PLC 对变频器的有效控制与监控&#xff0c;引入了开疆智能Etherne…...