C++链接FTP服务器并下载数据(在qt中编写)

.pro文件
#-------------------------------------------------
#
# Project created by QtCreator 2024-07-16T13:19:03
#
#-------------------------------------------------QT       += core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = untitled
TEMPLATE = app# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \FTPManager.cppHEADERS += \FTPManager.hFORMS += \FTPManager.uiLIBS += -lWininet
.h文件
#ifndef FTPMANAGER_H
#define FTPMANAGER_H#include <Windows.h>
#include <Wininet.h>
#include <QtDebug>
#include <QListWidget>
#include <QString>
#include <QFileDialog>
#include <QObject>class FTPManager : public QObject
{Q_OBJECT
public:FTPManager(); // 构造函数,初始化 WinINet~FTPManager(); // 析构函数,关闭连接// 连接到 FTP 服务器bool connectToFTP(const wchar_t* szHostName, const wchar_t* szUserName, const wchar_t* szPassword);// 断开 FTP 连接void disconnectFromFTP();// 列出 FTP 服务器上指定路径下的所有文件和文件夹bool listFilesAndDirectories(const wchar_t* szUrlPath, QListWidget* listWidget);// 下载 FTP 服务器上的单个文件bool downloadFileFromFTP(const wchar_t* szFileName, const wchar_t* szLocalPath);// 下载 FTP 服务器上指定路径的所有文件bool downloadDirectoryFromFTP(const wchar_t* szUrlPath, const wchar_t* szLocalPath);private:HINTERNET m_hInternet; // WinINet 打开的 Internet 连接句柄HINTERNET m_hConnect; // FTP 连接句柄
};#endif // FTPMANAGER_H
.cpp文件 
#include "FTPManager.h"FTPManager::FTPManager(): m_hInternet(NULL), m_hConnect(NULL)
{// 初始化 WinINetm_hInternet = InternetOpen(L"WinInet Ftp", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);if (!m_hInternet){qDebug() << "InternetOpen failed: " << GetLastError();}
}FTPManager::~FTPManager()
{// 析构函数,关闭 WinINet 相关资源if (m_hConnect)InternetCloseHandle(m_hConnect);if (m_hInternet)InternetCloseHandle(m_hInternet);
}bool FTPManager::connectToFTP(const wchar_t* szHostName, const wchar_t* szUserName, const wchar_t* szPassword)
{if (!m_hInternet){qDebug() << "Not connected to Internet";return false;}// 连接到 FTP 服务器m_hConnect = InternetConnect(m_hInternet, szHostName, INTERNET_DEFAULT_FTP_PORT, szUserName, szPassword, INTERNET_SERVICE_FTP, 0, 0);if (!m_hConnect){qDebug() << "InternetConnect failed: " << GetLastError();return false;}return true;
}void FTPManager::disconnectFromFTP()
{// 断开 FTP 连接if (m_hConnect){InternetCloseHandle(m_hConnect);m_hConnect = NULL;}
}bool FTPManager::listFilesAndDirectories(const wchar_t* szUrlPath, QListWidget* listWidget)
{if (!m_hConnect){qDebug() << "Not connected to FTP server";return false;}std::wstring searchPath = szUrlPath;if (searchPath.back() != L'/')searchPath += L"/";WIN32_FIND_DATAW findData;RtlZeroMemory(&findData, sizeof(WIN32_FIND_DATAW));// 执行 FTP 的查找操作HINTERNET hFind = FtpFindFirstFile(m_hConnect, (searchPath + L"*").c_str(), &findData, INTERNET_FLAG_RELOAD, 0);if (hFind == NULL){qDebug() << "FtpFindFirstFile failed: " << GetLastError();return false;}BOOL bNext = TRUE;// 循环读取文件和文件夹信息,并添加到 QListWidget 中显示while (bNext){// 如果是文件夹,则输出文件夹名称if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){std::wstring fileName = findData.cFileName;QString qFileName = QString::fromStdWString(fileName);QListWidgetItem* item = new QListWidgetItem(qFileName);listWidget->addItem(item);}bNext = InternetFindNextFile(hFind, &findData);}InternetCloseHandle(hFind);return true;
}bool FTPManager::downloadFileFromFTP(const wchar_t* szFileName, const wchar_t* szLocalPath)
{if (!m_hConnect){qDebug() << "Not connected to FTP server";return false;}// 打开 FTP 服务器上的文件HINTERNET hFile = FtpOpenFile(m_hConnect, szFileName, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, 0);if (!hFile){qDebug() << "FtpOpenFile failed: " << GetLastError();return false;}std::wstring localFilePath = szLocalPath;localFilePath += L"\\";localFilePath += szFileName;// 在本地创建文件HANDLE hLocalFile = CreateFile(localFilePath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (hLocalFile == INVALID_HANDLE_VALUE){qDebug() << "CreateFile failed: " << GetLastError();InternetCloseHandle(hFile);return false;}DWORD bytesRead = 0;BYTE buffer[1024];BOOL bRet = true;// 从 FTP 服务器读取文件内容,并写入到本地文件中while (InternetReadFile(hFile, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0){DWORD bytesWritten = 0;if (!WriteFile(hLocalFile, buffer, bytesRead, &bytesWritten, NULL)){qDebug() << "WriteFile failed: " << GetLastError();bRet = false;break;}}CloseHandle(hLocalFile);InternetCloseHandle(hFile);if (bRet){qDebug() << "File downloaded successfully: " << QString::fromStdWString(localFilePath);}return bRet;
}bool FTPManager::downloadDirectoryFromFTP(const wchar_t* szUrlPath, const wchar_t* szLocalPath)
{if (!m_hConnect){qDebug() << "Not connected to FTP server";return false;}std::wstring searchPath = szUrlPath;if (searchPath.back() != L'/')searchPath += L"/";WIN32_FIND_DATAW findData;RtlZeroMemory(&findData, sizeof(WIN32_FIND_DATAW));// 查找 FTP 服务器上的文件和文件夹HINTERNET hFind = FtpFindFirstFile(m_hConnect, (searchPath + L"*").c_str(), &findData, INTERNET_FLAG_RELOAD, 0);if (hFind == NULL){qDebug() << "FtpFindFirstFile failed: " << GetLastError();return false;}BOOL bNext = TRUE;BOOL bRet = true;// 下载 FTP 服务器上指定路径的所有文件到本地目录while (bNext){// 如果是文件,则下载文件if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){bRet = downloadFileFromFTP(findData.cFileName, szLocalPath);if (!bRet)break;}bNext = InternetFindNextFile(hFind, &findData);}InternetCloseHandle(hFind);return bRet;
}

 

main.cpp
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QListWidget>
#include <QPushButton>
#include <QFileDialog>
#include "FTPManager.h"int main(int argc, char *argv[])
{QApplication a(argc, argv);QWidget window;QVBoxLayout layout(&window);QListWidget listWidget;QPushButton btnList("列出文件");QPushButton btnDownloadFile("下载文件");QPushButton btnDownloadAll("下载全部");const wchar_t* szHostName = L"192.168.0.103";  // FTP服务器地址const wchar_t* szUserName = L"root";           // FTP登录用户名const wchar_t* szPassword = L"root";           // FTP登录密码const wchar_t* szUrlPath = L"/";               // FTP服务器上要列出文件和文件夹的路径const wchar_t* szLocalPath = L"C:\\Users\\ROG10030\\Desktop\\FTPDownload";  // 本地保存路径FTPManager ftpManager;// 点击按钮,列出文件和文件夹列表QObject::connect(&btnList, &QPushButton::clicked, [&]() {listWidget.clear();if (ftpManager.connectToFTP(szHostName, szUserName, szPassword)){qDebug() << "已连接到 FTP 服务器";ftpManager.listFilesAndDirectories(szUrlPath, &listWidget);ftpManager.disconnectFromFTP();}});// 点击按钮,下载单个文件QObject::connect(&btnDownloadFile, &QPushButton::clicked, [&]() {QString fileName = QFileDialog::getSaveFileName(nullptr, "保存文件", QDir::homePath());if (!fileName.isEmpty()){std::wstring wsFileName = fileName.toStdWString();if (ftpManager.connectToFTP(szHostName, szUserName, szPassword)){qDebug() << "已连接到 FTP 服务器";ftpManager.downloadFileFromFTP(wsFileName.c_str(), szLocalPath);ftpManager.disconnectFromFTP();}}});// 点击按钮,下载整个目录QObject::connect(&btnDownloadAll, &QPushButton::clicked, [&]() {if (ftpManager.connectToFTP(szHostName, szUserName, szPassword)){qDebug() << "已连接到 FTP 服务器";CreateDirectory(szLocalPath, NULL);ftpManager.downloadDirectoryFromFTP(szUrlPath, szLocalPath);ftpManager.disconnectFromFTP();}});layout.addWidget(&btnList);layout.addWidget(&listWidget);layout.addWidget(&btnDownloadFile);layout.addWidget(&btnDownloadAll);window.setLayout(&layout);window.resize(400, 300);window.show();return a.exec();
}

 点击列出文件则会将此目录下的文件显示到list中,下载全部没问题,单个下载需要选择文件,进行处理(未完全实现)

 

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

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

相关文章

Qt实现IP地址输入框-自定义控件

在 许多应用程序中&#xff0c;我们经常需要使用IP地址。为了方便用户输入和处理&#xff0c;一个好的解决方案是使用自定义控件。本示例代码使用Qt编写一个名为“IPAddress”的自定义控件来实现IP地址的输入功能。通过使用此控件&#xff0c;用户可以方便地输入和处理IP地址。…

吴恩达机器学习笔记 三十八 二进制标签 均值归一化

标签 0 和 1 可以有很多种意义。从回归到二分分类&#xff1a;之前定义 ,而对于二进制标签&#xff0c;通过给出y^(i,j)为 1 的概率&#xff0c;其中 损失函数 均值归一化 计算每个电影的平均得分&#xff0c;例如第一部电影的平均分为2.5&#xff0c;第五部电影的平均分为1.2…

如何在excel表中实现单元格满足条件时整行变色?

可以试试使用条件格式&#xff1a; 一、条件格式 所谓“自动变色”就要使用条件格式。 先简单模拟数据如下&#xff0c; 按 B列数字为偶数 为条件&#xff0c;整行标记为蓝色背景色。 可以这样设置&#xff1a; 先选中1:10行数据&#xff0c;在这里要确定一下名称栏里显示…

pico+unity3d手部动画

在 Unity 开发中&#xff0c;输入系统的选择和运用对于实现丰富的交互体验至关重要。本文将深入探讨 Unity 中的 Input System 和 XR Input Subsystem 这两种不同的输入系统&#xff0c;并详细介绍它们在控制手部动画方面的应用。 一、Input System 和 XR Input Subsystem 的区…

Java性能优化-书写高质量SQL的建议(如何做Mysql优化)

场景 Mysql中varchar类型数字排序不对踩坑记录&#xff1a; Mysql中varchar类型数字排序不对踩坑记录_mysql vachar排序有问题-CSDN博客 为避免开发过程中针对mysql语句的写法再次踩坑&#xff0c;总结开发过程中常用书写高质量sql的一些建议。 注&#xff1a; 博客&#…

Java面试题--JVM大厂篇之深入解析JVM中的Serial GC:工作原理与代际区别

目录 引言&#xff1a; 正文&#xff1a; 一、Serial GC工作原理 年轻代垃圾回收&#xff08;Minor GC&#xff09;&#xff1a; 老年代垃圾回收&#xff08;Major GC或Full GC&#xff09;&#xff1a; 二、年轻代和老年代的区别 年轻代&#xff08;Young Generation&a…

docker快速安装(环境CentOS7)

1. 查看自己的Linux系统 cat /etc/redhat-release 2. 安装依赖插件 yum -y install gcc yum -y install gcc-c yum install -y yum-utils yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum makecache fast yum -y insta…

MongoDB常用命令大全,概述、备份恢复

文章目录 一、MongoDB简介二、服务启动停止、连接三、数据库相关四、集合操作五、文档操作六、数据备份与恢复/导入导出数据6.1 mongodump备份数据库6.2 mongorestore还原数据库6.3 mongoexport导出表 或 表中部分字段6.4 mongoimport导入表 或 表中部分字段 七、其他常用命令八…

养猪管理如何实现远程监控

在现代化农业快速发展的背景下&#xff0c;养猪管理的智能化与远程监控技术的应用日益成为提升养殖效率、保障动物健康及优化资源配置的关键手段。实现养猪管理的远程监控&#xff0c;不仅能够实时掌握猪场环境参数与生猪生长状况&#xff0c;还能有效预防疾病、提高生产性能&a…

Spring Cloud环境搭建

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Spring学习之路&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1. 开发环境安装 1.1 安装JDK ​1.2 安装MySQL 2. 案列介绍 2.1 …

C语言指针超详解——进阶篇

C语言指针系列文章目录 入门篇 强化篇 进阶篇 文章目录 C语言指针系列文章目录1. 字符指针变量2. 数组指针变量2. 1 概念2. 2 数组指针变量的初始化 3. 二维数组传参的本质4. 函数指针变量4. 1 函数指针变量的创建4. 2 指针变量的使用4. 3 两个有趣的代码4. 3. 1 代码一4. 3. …

汽车底盘控制系统Autosar初步接触

最近接触到汽车底盘控制部分&#xff0c;作为小白&#xff0c;原以为汽车底盘也是要自己手敲代码&#xff0c;结果发现完全不是。记录一下最近的学习心得&#xff0c;初步接触东西不全&#xff0c;但可以当作参考。 对于底盘控制部分的简单理解&#xff1a;simulink做汽车底盘的…

大数据技术基础

一、大数据平台 1.大数据平台方案步骤&#xff1a; ①市场上有哪些大数据平台 ②硬件、系统、业务增长等方面 ③方案是否通过 通过后&#xff1a;按照一期目标投入 先虚拟环境部署联系&#xff0c;再实际部署 《大数据架构介绍》《Hadoop架构解析》《Hadoop集群规划》 《H…

PX4 运行 make px4_sitl_default gazebo 报错

报错原因&#xff1a;最开始我把依赖一直都是在base环境下安装的&#xff0c;没有conda deactivate&#xff0c;而pip install的东西应该装在系统环境&#xff0c;不能装在base环境下&#xff0c;sudo apt 是装在系统环境的 1.检查ros 用鱼香ros安装 wget http://fishros.…

南平建网站公司推荐 好用的b2b独立站模板

床品毛巾wordpress独立站模板 床单、被套、毛巾、抱枕、靠垫、围巾、布艺、枕头、乳胶枕、四件套、浴巾wordpress网站模板。 https://www.jianzhanpress.com/?p4065 打印耗材wordpress自建独立站模板 色带、墨盒、碳粉、打印纸、硒鼓、墨盒、墨水、3D打印机、喷头wordpress…

Pr 2024下载安装,Adobe Premiere pro2024剪辑软件下载合集获取

Premiere Pro 2023中文版简称Pr&#xff0c;pr2023是一款视频编辑软件。 pr 2023不仅可以帮助用户对各种视频进行剪辑、旋转、分割、合并、字幕添加、背景音乐等基础的处理&#xff0c;还能帮助用户进行视频颜色校正、颜色分级、稳定镜头、调整层、更改片段的持续时间和速度、效…

Sentinel规则持久化Push模式两种实现方式

文章目录 sentinel持久化push推模式微服务端的实现具体实现源码分析读数据源写数据源的实现 微服务端解析读数据源流程 修改源码的实现官方demo修改源码实现配置类flowauthoritydegreadparamsystemgateway修改源码 测试补充 前置知识 pull模式 sentinel持久化push推模式 pull拉…

Pycharm 导入 conda 环境

使用时经常在此处卡壳&#xff0c;在此做个记录。 这个位置选择 conda 安装路径下的 python.exe 文件即可

自学鸿蒙HarmonyOS的ArkTS语言<十>@BuilderParam装饰器

作用&#xff1a;当子组件多处使用时&#xff0c;给某处的子组件添加特定功能 一、初始化 1、只能被Builder装饰的方法初始化 2、使用所属自定义组件的builder方法初始化 3、使用父组件的builder方法初始化 - 把父组件的builder传过去&#xff0c;参数名和子组件的builderPar…

ESP32部署TensorFlow Lite

本来是想找一篇中文教程&#xff0c;不过只看到一个英文官方的&#xff0c;也行吧&#xff0c;虽然效率会慢丢丢。 GitHub - espressif/esp-tflite-micro: TensorFlow Lite Micro for Espressif Chipsets 看了一圈&#xff0c;有个中文的&#xff1a; esp-dl/README_cn.md a…