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://xiahunao.cn/news/3246757.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

通过SchedulingConfigurer 接口完成动态定时任务

通过SchedulingConfigurer 接口完成动态定时任务 一.背景 在Spring中&#xff0c;除了使用Scheduled注解外&#xff0c;还可以通过实现SchedulingConfigurer接口来创建定时任务。它们之间的主要区别在于灵活性和动态性。Scheduled注解适用于固定周期的任务&#xff0c;一旦任…

【C++数据结构】二叉搜索树(超详细图解操作过程,超详细讲解代码实现)

目录 01.二叉搜索树的概念 02.二叉搜索树的操作过程 03.二叉搜索树的代码实现 &#xff08;1&#xff09;基本框架 &#xff08;2&#xff09;树的创建与销毁 &#xff08;3&#xff09;元素的查找 &#xff08;4&#xff09;元素的插入 &#xff08;5&#xff09;元素的…

Day71 代码随想录打卡|回溯算法篇---全排列

题目&#xff08;leecode T46&#xff09;&#xff1a; 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 方法&#xff1a;全排列是数学中的基础问题&#xff0c;也是回溯算法能解决的经典问题。全排列因为每个元素都会…

卷积神经网络学习问题总结

问题一&#xff1a; 深度学习中的损失函数和应用场景 回归任务&#xff1a; 均方误差函数&#xff08;MSE&#xff09;适用于回归任务&#xff0c;如预测房价、预测股票价格等。 import torch.nn as nn loss_fn nn.MSELoss() 分类任务&#xff1a; 交叉熵损失函数&…

AI算法19-偏最小二乘法回归算法Partial Least Squares Regression | PLS

偏最小二乘法回归算法简介 算法概述 偏最小二乘法模型可分为偏最小二乘回归模型和偏最小二乘路径模型。其中偏最小二乘回归模型是一种新型的多元统计方法&#xff0c;它集中了主成分分析、典型相关分析和线性回归的特点&#xff0c;特别在解决回归中的共线性问题具有无可比拟…

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.…

日活2.5亿的Twitter 使用了哪些数据库?

Twitter 使用什么数据库存储用户每天发送的数亿条推文&#xff1f;是 SQL、NoSQL 还是其它持久化存储系统&#xff1f; Twitter 使用什么数据库&#xff1f; 任何一个稍微有点规模的系统其存储层绝不会只使用一种数据库&#xff0c;服务于数以亿计用户的Twitter更是如此。Twit…

《YOLOv10改进实战专栏》专栏介绍 专栏目录

《YOLOv10改进实战专栏》介绍及目录 YOLOv10官方仓库地址 专栏地址&#xff1a;点击跳转 专栏导航如下&#xff1a; &#x1f380;基础入门篇&#x1f380; 万字长文&#xff0c;小白新手怎么开始做YOLO实验&#xff0c;从零开始教&#xff01;整体思路在这里&#xff0c;科研指…

Vue学习---vue cli 项目创建

使用的编辑工具webStorm 创建例子: hello vue create hello 选择 vue3 进行创建 运行 npm run serve 测试访问&#xff1a;http://localhost:8080 改动内容重新编译&#xff1a; npm run build dist 目录就是编译后的可运行内容

浅谈C嘎嘎类与对象

本篇文章与大家浅谈一下C嘎嘎的类与对象知识点 类的定义 关键字&#xff1a;class 语法格式&#xff1a; class 类名 { }&#xff1b;//这里的分号不能少 此外&#xff0c;class有三个属性分别是private、public、protected&#xff0c;这三个属性是干啥的&#xff0c;相…

MSPM0G3507——时钟主频拉到80MHZ

先点开使用时钟树 在配置时钟界面这样配置

Ghost Browser指纹浏览器年+IPXProxy代理IP组合:SheIn卖家必看

SheIn是一家时尚电商公司&#xff0c;其用户数量近年来增长迅速&#xff0c;在全球的知名度越来越高。SheIn跨境电商卖家想要提升店铺曝光和排名&#xff0c;从而增加销量和信誉的话&#xff0c;就需要满足独立IP、模拟设备参数、独立环境等条件。同时满足这些条件的话就需要用…

生成式人工智能(AI)的未来

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

windows qt编译报错 无法打开包括文件: “EGL/egl.h”: No such file or directory

windows mingw32 qt creator QtAV 推荐ffmpeg依赖包 QT5.14.2 如果出现&#xff1a;无法打开包括文件: “EGL/egl.h”: No such file or directory 可能是Qt6的问题.在QT5上安装。 编译步骤&#xff1a; git clone https://github.com/wang-bin/QtAV.git cd QtAV &&…

【深度学习教程】

文章目录 pytorch官方教程知识蒸馏&#xff1a;https://pytorch.org/tutorials/beginner/knowledge_distillation_tutorial.html 李宏毅-机器学习/深度学习https://speech.ee.ntu.edu.tw/~hylee/ml/2021-spring.phphttps://speech.ee.ntu.edu.tw/~hylee/ml/2022-spring.phphttp…

最新Qt6的下载与成功安装详细介绍

引言 Qt6 是一款强大的跨平台应用程序开发框架&#xff0c;支持多种编程语言&#xff0c;最常用的是C。Qt6带来了许多改进和新功能&#xff0c;包括对C17的支持、增强的QML和UI技术、新的图形架构&#xff0c;以及构建系统方面的革新。本文将指导你如何在Windows平台上下载和安…

第五章:卷-将磁盘挂载到容器

本章内容包括&#xff1a; 创建多容器pod创建一个可在容器间共享磁盘存储的卷在pod中使用git仓库将持久性存储挂载到pod使用预先配置的持久性存储动态调配持久存储 在前面说过&#xff0c;pod类似逻辑主机&#xff0c;在逻辑主机中运行的进程共享如CPU、RAM、网络接口等资源&am…

一分钟了解什么是1U,2U服务器?

一、什么是1U&#xff0c;2U服务器&#xff1f; 什么是1U服务器呢&#xff1f;所谓的1U服务器就是一种高可用高密度的低成本服务器平台&#xff0c;U是服务器机箱的高度 1U等于4.45厘米 &#xff0c;那3U就是3x4.5CM了。 u(unit的缩略语)是一种表示组合式机架外部尺寸的单位&a…

【时时三省】tessy 集成测试:小白入门指导手册

目录 1,创建集成测试模块且分析源文件 2,设置测试环境 3,TIE界面设置相关函数 4,SCE界面增加用例 5,编辑数据 6,用例所对应的测试函数序列 7,添加 work task 函数 8,为测试场景添加函数 9,为函数赋值 10,编辑时间序列的数值 11,执行用例 12,其他注意事项…

【论文阅读】(StemGNN)多元时间序列预测的谱时间图神经网络

&#xff08;StemGNN&#xff09;Spectral Temporal Graph Neural Network for Multivariate Time-series Forecasting 引用&#xff1a; Cao D , Wang Y , Duan J ,et al.Spectral Temporal Graph Neural Network for Multivariate Time-series Forecasting[J]. 2021.DOI:10.…