您的位置:首页 > 科技 > IT业 > C++链接FTP服务器并下载数据(在qt中编写)

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

2024/12/23 5:58:58 来源:https://blog.csdn.net/qq_60797167/article/details/140470774  浏览:    关键词: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中,下载全部没问题,单个下载需要选择文件,进行处理(未完全实现)

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com