C/C++ 实现FTP文件上传下载
FTP(文件传输协议)是一种用于在网络上传输文件的标准协议。它属于因特网标准化的协议族之一,为文件的上传、下载和文件管理提供了一种标准化的方法,在Windows系统中操作FTP上传下载可以使用WinINet库,WinINet(Windows Internet)库是 Windows 操作系统中的一个网络 API 库,用于访问 Internet 上的资源。它提供了一组函数,使开发人员能够创建网络应用程序,例如通过 HTTP 协议下载文件,发送 HTTP 请求,处理 cookie 等,本章将通过使用WinInet所提供的接口实现FTP文件上传下载功能,使得用户可以通过代码的方式上传或下载文件与FTP服务器交互。
首先读者需要自行搭建FTP服务器,这里可以使用20CN Mini Ftp
这款迷你FTP服务器,配置好信息之后运行即可;
- 服务器下载地址:https://download.csdn.net/download/lyshark_csdn/88583789
接着来介绍实现FTP通信的标准API函数信息,其核心的函数如下所示;
InternetOpen
函数,用于初始化 WinINet 库,返回一个句柄,该句柄可用于后续的网络操作。以下是该函数的原型和简要说明:
HINTERNET InternetOpen(LPCWSTR lpszAgent, // 用户代理字符串,标识应用程序的名称DWORD dwAccessType, // 访问类型,可以是 DIRECT、PRECONFIG 或 PROXYLPCWSTR lpszProxyName, // 代理服务器名称LPCWSTR lpszProxyBypass, // 代理服务器的绕过列表DWORD dwFlags // 一些标志,例如INTERNET_FLAG_ASYNC(异步操作)
);
lpszAgent
: 用户代理字符串,用于标识应用程序的名称。可以是应用程序的名称或标识符。dwAccessType
: 访问类型,指定应用程序的访问权限。可以是以下值之一:INTERNET_OPEN_TYPE_DIRECT
: 直接访问互联网。INTERNET_OPEN_TYPE_PRECONFIG
: 使用系统配置的代理。INTERNET_OPEN_TYPE_PROXY
: 使用指定的代理。
lpszProxyName
: 代理服务器的名称,仅在dwAccessType
为INTERNET_OPEN_TYPE_PROXY
时使用。lpszProxyBypass
: 代理服务器的绕过列表,仅在dwAccessType
为INTERNET_OPEN_TYPE_PROXY
时使用。dwFlags
: 一些标志,用于指定其他选项,例如INTERNET_FLAG_ASYNC
表示执行异步操作。
该函数返回一个 HINTERNET
句柄,用于后续的网络操作。如果操作失败,返回 NULL
。在使用完 HINTERNET
句柄后,应该使用 InternetCloseHandle
函数关闭该句柄。
InternetConnect
函数,用于创建一个与指定服务器的连接。以下是该函数的原型和简要说明:
HINTERNET InternetConnect(HINTERNET hInternet, // InternetOpen 返回的句柄LPCWSTR lpszServerName, // 服务器的主机名INTERNET_PORT nServerPort, // 服务器的端口号LPCWSTR lpszUsername, // 用户名LPCWSTR lpszPassword, // 密码DWORD dwService, // 服务类型,例如 INTERNET_SERVICE_HTTPDWORD dwFlags, // 一些标志,例如 INTERNET_FLAG_RELOADDWORD_PTR dwContext // 应用程序定义的上下文
);
hInternet
: 由InternetOpen
返回的句柄,表示与 WinINet 库的连接。lpszServerName
: 服务器的主机名或 IP 地址。nServerPort
: 服务器的端口号。lpszUsername
: 连接需要的用户名。lpszPassword
: 连接需要的密码。dwService
: 服务类型,可以是以下值之一:INTERNET_SERVICE_FTP
: FTP 服务INTERNET_SERVICE_HTTP
: HTTP 服务- 其他服务类型,具体可查阅官方文档。
dwFlags
: 一些标志,例如INTERNET_FLAG_RELOAD
表示重新加载页面。dwContext
: 应用程序定义的上下文,可以是一个指针。
该函数返回一个 HINTERNET
句柄,用于后续的网络操作。如果操作失败,返回 NULL
。在使用完 HINTERNET
句柄后,应该使用 InternetCloseHandle
函数关闭该句柄。
InternetWriteFile
函数,用于向已打开的互联网文件或句柄写入数据。以下是该函数的原型和简要说明:
BOOL InternetWriteFile(HINTERNET hFile, // 由 InternetOpenUrl 或 HttpOpenRequest 返回的文件句柄LPCVOID lpBuffer, // 指向包含要写入的数据的缓冲区的指针DWORD dwNumberOfBytesToWrite, // 要写入的字节数LPDWORD lpdwNumberOfBytesWritten // 指向接收实际写入的字节数的指针
);
hFile
: 由InternetOpenUrl
或HttpOpenRequest
返回的文件句柄。lpBuffer
: 指向包含要写入的数据的缓冲区的指针。dwNumberOfBytesToWrite
: 要写入的字节数。lpdwNumberOfBytesWritten
: 指向接收实际写入的字节数的指针。
该函数返回一个布尔值,指示操作是否成功。如果成功,返回 TRUE
,否则返回 FALSE
。
InternetReadFile
函数,用于从已打开的互联网文件或句柄读取数据。以下是该函数的原型和简要说明:
BOOL InternetReadFile(HINTERNET hFile, // 由 InternetOpenUrl 或 HttpOpenRequest 返回的文件句柄LPVOID lpBuffer, // 指向接收数据的缓冲区的指针DWORD dwNumberOfBytesToRead, // 要读取的字节数LPDWORD lpdwNumberOfBytesRead // 指向接收实际读取的字节数的指针
);
hFile
: 由InternetOpenUrl
或HttpOpenRequest
返回的文件句柄。lpBuffer
: 指向接收数据的缓冲区的指针。dwNumberOfBytesToRead
: 要读取的字节数。lpdwNumberOfBytesRead
: 指向接收实际读取的字节数的指针。
该函数返回一个布尔值,指示操作是否成功。如果成功,返回 TRUE
,否则返回 FALSE
。
FTP文件下载
如下代码是使用 WinInet 库实现的 FTP 文件下载功能。以下是对该代码的概述:
- 头文件引入和库链接:
- 代码使用了
<Windows.h>
和<WinInet.h>
头文件,同时通过#pragma comment(lib, "WinInet.lib")
链接了 WinInet 库,这是使用 WinInet 库的基本准备工作。
- 代码使用了
FtpSaveToFile
函数:- 该函数用于将数据保存到本地文件。它通过调用
CreateFile
创建一个空文件,然后使用WriteFile
将数据写入文件,最后关闭文件句柄。这个函数在 FTP 文件下载后保存文件到本地。
- 该函数用于将数据保存到本地文件。它通过调用
FTPDownload
函数:- 这是主要的 FTP 下载函数。它使用 WinInet 提供的函数建立了一个 FTP 会话,连接到指定的 FTP 服务器,打开指定路径的文件,并通过循环调用
InternetReadFile
读取文件内容。 - 下载的数据以字节数组的形式保存在
pDownloadData
中,下载完成后,调用FtpSaveToFile
函数将数据保存到本地文件。
- 这是主要的 FTP 下载函数。它使用 WinInet 提供的函数建立了一个 FTP 会话,连接到指定的 FTP 服务器,打开指定路径的文件,并通过循环调用
- 注意事项:
- 代码中使用了
RtlZeroMemory
函数清空内存,确保数据缓冲区的正确初始化。 - 注意释放动态分配的内存,避免内存泄漏。
- 代码中使用了
- 函数参数:
- 函数参数包括 FTP 服务器的主机名 (
szHostName
)、用户名 (szUserName
)、密码 (szPassword
)、FTP 路径 (szUrlPath
),以及本地保存路径 (SavePath
)。
- 函数参数包括 FTP 服务器的主机名 (
总体而言,这段代码实现了基本的 FTP 文件下载功能,适用于从 FTP 服务器下载文件到本地。在使用时,确保提供正确的 FTP 服务器信息和路径,以及合适的本地保存路径。
#include <iostream>
#include <Windows.h>
#include <WinInet.h>#pragma comment(lib, "WinInet.lib")// 保存文件到本地
BOOL FtpSaveToFile(char *pszFileName, BYTE *pData, DWORD dwDataSize)
{// 创建空文件HANDLE hFile = CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE, NULL);if (INVALID_HANDLE_VALUE == hFile)return FALSE;DWORD dwRet = 0;// 写出数据到文件WriteFile(hFile, pData, dwDataSize, &dwRet, NULL);// 关闭句柄CloseHandle(hFile);return TRUE;
}BOOL FTPDownload(char *szHostName, char *szUserName, char *szPassword, char *szUrlPath, char *SavePath)
{HINTERNET hInternet, hConnect, hFTPFile = NULL;BYTE *pDownloadData = NULL;DWORD dwDownloadDataSize = 0;DWORD dwBufferSize = 4096;BYTE *pBuf = NULL;DWORD dwBytesReturn = 0;DWORD dwOffset = 0;BOOL bRet = FALSE;// 建立会话并打开FTP操作hInternet = InternetOpen("WinInet Ftp", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);hConnect = InternetConnect(hInternet, szHostName, INTERNET_INVALID_PORT_NUMBER,szUserName, szPassword, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);hFTPFile = FtpOpenFile(hConnect, szUrlPath, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD, NULL);// 获取文件大小并初始化缓冲区dwDownloadDataSize = FtpGetFileSize(hFTPFile, NULL);pDownloadData = new BYTE[dwDownloadDataSize];RtlZeroMemory(pDownloadData, dwDownloadDataSize);pBuf = new BYTE[dwBufferSize];RtlZeroMemory(pBuf, dwBufferSize);// 循环接收数据do{// 读取数据bRet = InternetReadFile(hFTPFile, pBuf, dwBufferSize, &dwBytesReturn);if (FALSE == bRet)break;// 将读取到的数据追加到内存RtlCopyMemory((pDownloadData + dwOffset), pBuf, dwBytesReturn);dwOffset = dwOffset + dwBytesReturn;} while (dwDownloadDataSize > dwOffset);// 保存变量中的数据为文件FtpSaveToFile(SavePath, pDownloadData, dwDownloadDataSize);// 释放内存delete[]pDownloadData;pDownloadData = NULL;return TRUE;
}
调用FTPDownload
时分别传入参数,参数1是IP地址,参数2是FTP登录用户名,参数3是FTP登录密码,参数4是服务器端根目录下的文件,参数5是下载文件到本地的路径,函数执行结束后返回一个BOOL状态值。
int main(int argc, char * argv[])
{BOOL bRET = FTPDownload("127.0.0.1", "admin", "admin", "/lyshark.jpg", "d://newtest/lyshark.jpg");if (bRET == TRUE){printf("已下载文件 \n");}else{printf("下载失败 \n");}system("pause");return 0;
}
运行后则可以将服务器端上的/lyshark.jpg
下载到本地的d://newtest/lyshark.jpg
目录下,如下图所示;
FTP文件上传
如下代码使用 WinInet 库实现了 FTP 文件上传操作。以下是对该代码的概述:
- 函数功能:
- 该代码实现了 FTP 文件上传操作,将本地文件上传到指定的 FTP 服务器路径。
- 函数参数:
- 函数参数包括 FTP 服务器的主机名 (
szHostName
)、用户名 (szUserName
)、密码 (szPassword
)、FTP 路径 (szUrlPath
),以及本地文件路径 (FilePath
)。
- 函数参数包括 FTP 服务器的主机名 (
- 建立会话和连接:
- 使用
InternetOpen
函数建立一个 WinInet 会话,然后使用InternetConnect
函数建立到 FTP 服务器的连接。
- 使用
- 打开 FTP 文件:
- 使用
FtpOpenFile
函数打开指定路径的 FTP 文件。如果文件不存在,将创建一个新文件。文件以二进制传输方式打开,并且具有重新加载标志。
- 使用
- 打开本地文件:
- 使用
CreateFile
函数打开本地文件。如果本地文件不存在,将返回INVALID_HANDLE_VALUE
。
- 使用
- 获取文件大小和读取文件数据:
- 通过
GetFileSize
获取本地文件大小,然后根据文件大小动态分配内存,并使用ReadFile
读取文件数据到内存中。
- 通过
- 上传数据:
- 使用
InternetWriteFile
函数将内存中的文件数据上传到 FTP 服务器。上传成功后释放内存,上传失败则返回 FALSE。
- 使用
- 注意事项:
- 确保提供正确的 FTP 服务器信息和路径,以及本地文件路径。
- 释放动态分配的内存,避免内存泄漏。
- 处理上传失败的情况,可能需要添加适当的错误处理代码。
总体而言,这段代码实现了基本的 FTP 文件上传功能,适用于将本地文件上传到 FTP 服务器。在使用时,注意提供正确的参数和处理可能出现的错误。
#include <iostream>
#include <Windows.h>
#include <WinInet.h>#pragma comment(lib, "WinInet.lib")// 实现文件上传操作
BOOL FTPUpload(char *szHostName, char *szUserName, char *szPassword, char *szUrlPath, char *FilePath)
{HINTERNET hInternet, hConnect, hFTPFile = NULL;DWORD dwBytesReturn = 0;DWORD UploadDataSize = 0;BYTE *pUploadData = NULL;DWORD dwRet, bRet = 0;// 建立会话并打开FTP操作hInternet = InternetOpen("WinInet Ftp", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);hConnect = InternetConnect(hInternet, szHostName, INTERNET_INVALID_PORT_NUMBER, szUserName, szPassword, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);hFTPFile = FtpOpenFile(hConnect, szUrlPath, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD, NULL);// 打开文件HANDLE hFile = CreateFile(FilePath, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE, NULL);if (INVALID_HANDLE_VALUE == hFile)return FALSE;// 获取文件大小UploadDataSize = GetFileSize(hFile, NULL);pUploadData = new BYTE[UploadDataSize];// 读取文件到缓冲区ReadFile(hFile, pUploadData, UploadDataSize, &dwRet, NULL);UploadDataSize = dwRet;// 开始上传数据bRet = InternetWriteFile(hFTPFile, pUploadData, UploadDataSize, &dwBytesReturn);if (FALSE == bRet){delete[]pUploadData;return FALSE;}delete[]pUploadData;return TRUE;
}
文件上传与下载一样,FTPUpload
通过传入服务器地址,用户名,密码,上传后的文件名,被上传本地文件路径;
int main(int argc, char * argv[])
{BOOL bRET = FTPUpload("127.0.0.1", "admin", "admin", "/abc.exe", "c://nc.exe");if (bRET == TRUE){printf("已上传文件 \n");}else{printf("上传失败 \n");}system("pause");return 0;
}
上传成功后输出如下图所示;
相关文章:

C/C++ 实现FTP文件上传下载
FTP(文件传输协议)是一种用于在网络上传输文件的标准协议。它属于因特网标准化的协议族之一,为文件的上传、下载和文件管理提供了一种标准化的方法,在Windows系统中操作FTP上传下载可以使用WinINet库,WinINetÿ…...

第十三章 python之爬虫
Python基础、函数、模块、面向对象、网络和并发编程、数据库和缓存、 前端、django、Flask、tornado、api、git、爬虫、算法和数据结构、Linux、设计题、客观题、其他 第十三章 爬虫 1. 写出在网络爬取过程中, 遇到防爬问题的解决办法。 在网络爬取过程中,可能会遇…...

scrum 敏捷开发
scrum 敏捷开发 Scrum 是一种敏捷软件开发方法,旨在通过迭代、增量和协作的方式提高团队的效率和产品质量。下面是关于 Scrum 的一些重要概念和实践: 1. Scrum 团队角色 Scrum 团队通常由以下角色组成: 产品负责人(Product Ow…...

亚信科技AntDB数据库完成中国信通院数据库迁移工具专项测试
近日,在中国信通院“可信数据库”数据库迁移工具专项测试中,湖南亚信安慧科技有限公司(简称:亚信安慧科技)数据库数据同步平台V2.1产品依据《数据库迁移工具能力要求》、结合亚信科技AntDB分布式关系型数据库产品&…...

深度学习(一):Pytorch之YOLOv8目标检测
1.YOLOv8 2.模型详解 2.1模型结构设计 和YOLOv5对比: 主要的模块: ConvSPPFBottleneckConcatUpsampleC2f Backbone ----->Neck------>head Backdone 1.第一个卷积层的 kernel 从 6x6 变成了 3x3 2. 所有的 C3 模块换成 C2f,可以发现…...

EasyExcel如何读取全部Sheet页数据方法
一、需求描述 Excel表格里面大约有20个sheet页,每个sheet页65535条数据,需要读取全部数据,并导入至数据库。 找了好多种方式,EasyExcel比较符合,下面看代码。 二、实现方式 采用EasyExcel框架的doReadAll()方法 1、…...

GDPU 数据结构 天码行空12
文章目录 数据结构实验十二 图的遍历及应用一、【实验目的】二、【实验内容】三、实验源代码🍻 CPP🍻 C 数据结构实验十二 图的遍历及应用 一、【实验目的】 1、 理解图的存储结构与基本操作; 2、熟悉图的深度度优先遍历和广度优先遍历算法…...

什么是 Proxy?
目录 Proxy 的作用 1. 流量过滤 2. 记录日志 3. 加快访问速度 4. 隐藏 IP 地址 Proxy 的分类 1. 按协议分类 - HTTP 代理:只支持 HTTP 协议的代理服务器,它可以缓存 HTTP 请求和响应并过滤 HTTP 流量。 - FTP 代理:只支持 FTP 协议的…...

Vue系列:Vue Element UI中,使用按钮实现视频的播放、停止、停止后继续播放、播放完成后重新播放功能
最近在工作中有个政务大屏用到了视频播放; 技术栈是Vue2、Element UI; 要实现的功能是:使用按钮实现视频的播放、停止、停止后继续播放、播放完成后重新播放功能 具体可以按照以下步骤进行操作: 引入插件: 在Vue组件…...

.Net 8 Blazor下 Auto交互渲染模式试用
一、环境 C:\Users\zhuji>dotnet --version 8.0.100C:\Users\zhuji>dotnet --list-sdks 5.0.403 [C:\Program Files\dotnet\sdk] 6.0.404 [C:\Program Files\dotnet\sdk] 8.0.100 [C:\Program Files\dotnet\sdk] Microsoft Visual Studio Enterprise 2022 (64 位) - Cu…...

AndroidStudio - 新版本 Logcat 使用详解
最近这俩天正好有时间给自己做一下减法,忘记是去年还是今年,在升级 AndroidStudio 后使用 Logcat查看日志的方式也发生了一些变化,虽然一直在使用,但每当看到之前还未关闭 Logcat 命令行工具额昂也,就感觉可能还存在知…...

Webpack ECMAScript 模块
文章目录 前言标题一导出导入将模块标记为 ESM 后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:webpack 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误&a…...

knife4j集合化postman
knife4j集合化postman 01 knife4j的介绍 基于 JavaMVC的集成框架swagger的进一步强化,在原有通过注释就能生成文档的前身swagger-bootstrap-ui之上,增加了postman的测试功能,优化了文档的UI界面,在测试api接口的方面有了极大的进…...

MongoDB的原子性和多文档事务处理
原子性和事务处理是数据库操作的核心,保证了数据的准确性。依据数据库原子性,数据库和使用数据库的人员定义事务处理的方式。本文依据Mongodb的官方文档,整理Mongodb数据库的原子性和事务处理方法。 Mongodb的原子操作 Mongodb中,…...

代理模式 1、静态代理 2、动态代理 jdk自带动态代理 3、Cglib代理
文章目录 代理模式1、静态代理2、动态代理jdk自带动态代理 3、Cglib代理 来和大家聊聊代理模式 代理模式 代理模式:即通过代理对象访问目标对象,实现目标对象的方法。这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操…...

ELK+filebeat+kafka
无需创建logstash的端口,直接创建topic 远程收集mysql和httpd的日志 (一)安装nginx和mysql服务 1、打开mysql的日志功能 2、创建日志(创库、创表、添加数据) (1)mysql服务器上安装http system…...

LLVM学习笔记(63)
4.4.3.3.2.3. 向量操作数类型的处理 下面开始处理向量类型。在默认情形下这些操作都会拆分为更小的操作或者调用库。 X86TargetLowering::X86TargetLowering(续) 667 // Some FP actions are always expanded for vector types. 668 for…...

【python+requests】接口自动化测试
这两天一直在找直接用python做接口自动化的方法,在网上也搜了一些博客参考,今天自己动手试了一下。 一、整体结构 上图是项目的目录结构,下面主要介绍下每个目录的作用。 Common:公共方法:主要放置公共的操作的类,比如数据库sql…...

plt创建指定色系
1、创建不连续色系 import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap# 定义颜色的RGB值 colors [(0.2, 0.4, 0.6), # 蓝色(0.8, 0.1, 0.3), # 红色(0.5, 0.7, 0.2),(0.3,0.5,0.8)] # 绿色# 创建色系 cmap ListedColormap(colors)# 绘制…...

Java多线程-第20章
Java多线程-第20章 1.创建线程 Java是一种支持多线程编程的编程语言。多线程是指在同一程序中同时执行多个独立任务的能力。在Java中,线程是一种轻量级的子进程,它是程序中的最小执行单元。Java的多线程编程可以通过两种方式实现:继承Threa…...

寿险公司通过开源治理保障数字创新,安全打通高质量服务新通道
某寿险公司致力于为消费者提供人性化的产品和服务,在中国保险市场中始终保持前列。该寿险公司以挖掘和满足客户需求为出发点,从产品开发、渠道销售、运营流程和售后服务等各环节,借助数字化工具,不断地努力探索并提升服务品质。 精…...

SpringBoot中的部分注解
1.SpringBoot/spring SpringBootApplication: 包含Configuration、EnableAutoConfiguration、ComponentScan通常用在主类上; Repository: 用于标注数据访问组件,即DAO组件; Service: 用于标注业务层组件; RestController: 用…...

蓝桥杯-02-蓝桥杯C/C++组考点与14届真题
文章目录 蓝桥杯C/C组考点与14届真题参考资源C/C组考点1. 组别2. 竞赛赛程3. 竞赛形式4. 参赛选手机器环境5. 试题形式5.1. 结果填空题5.2. 编程大题 6. 试题考查范围7. 答案提交8. 评分9. 样题样题 1:矩形切割(结果填空题)样题 2:…...

计算机杂谈系列精讲100篇-【计算机应用】关于TensorFlow和PyTorch的一些看法
目录 前言 知识储备 PyTorch使用高频代码 导入包和版本查询...

Uni-App知识点
文章目录 一、事件总线二、什么是事件总线三、触发事件1、监听事件2、只监听一次3、移除监听4、触发事件注意事项5、代码示例6、注意事项 一、事件总线 除了父子组件传参之外,兄弟组件之间共享信息也是我们经常会遇到的。如果遇到这类问题,我们现在可以…...

Postman如何使用(四):接口测试
一.接口 1.程序内部接口:方法与方法之间,模块与模块之间的交互,程序内部抛出的接口,比如bbs系统,有登录模块,发帖模块等等,那你要发帖就必须先登录,那么这两个模块就得有交互&#…...

【Qt绘图】之绘制坦克
使用绘图事件,绘制坦克。 效果 效果很逼真,想象力,有没有。 示例 代码像诗一样优雅,有没有。 包含头文件 #include <QApplication> #include <QWidget> #include <QPainter>绘制坦克类 class TankWidge…...

【机器视觉技术栈】- 机器视觉基础
1.1 为什么采用机器视觉 人眼与机器视觉对比 人眼机器视觉精确性差,64灰度级,不能分辨小于100微米的目标强,256灰度级,可检测微米级目标速度慢,无法看清间隔小于40毫秒的运动目标快,快门时间可达10微秒适…...

Arkts开发UIAbility组件生命周期启动模式开发详解【鸿蒙专栏-19】
文章目录 HarmonyOS UIAbility组件详解UIAbility组件概述声明配置UIAbility组件生命周期Create状态WindowStageCreate和WindowStageDestroy状态Foreground和Background状态Destroy状态UIAbility组件启动模式Singleton启动模式Standard启动模式Specified启动模式HarmonyOS UIAbi…...

力扣295. 数据流的中位数(java,堆解法)
Problem: 295. 数据流的中位数 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 由于该题目的数据是动态的我们可以维护两个堆来解决该问题 1.维护一个大顶堆,一个小顶堆 2.每个堆中元素个数接近n/2;如果n是偶数,两个堆中的数据个数…...