MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Проблема с кодировкой в названиях файлов на кириллице полученных с помощью FtpFindFirstFile"
Answer 1148428
Думаю у функции FtpFindFirstFile есть какие то особенности
Похоже, FtpFindFirstFile, даже Юникод-версия, не поддерживают имена файлов в кодировке UTF-8. Первый стандарт FTP разрешал имена файлов только из ASCII-символов, но впоследствии была добавлена необязательная поддержка имен на UTF-8 (кодировки ANSI FTP не использует). Но реализация FTP в WinInet как будто, даже если сервер поддерживает UTF-8, обрабатывает имена файлов, используя текущую системную кодовую страницу ANSI. Поэтому единственный выход - вручную перекодировать через MultiByteToWideChar:
#include <stdlib.h> #include <iostream> #include <io.h> #include <fcntl.h> #include <vector> #include <Windows.h> #include <WinInet.h> #pragma comment(lib,"wininet") inline std::vector<std::wstring> scanDir(HINTERNET hInternetConnection, std::wstring dir) { std::vector<std::wstring> files; if (!FtpSetCurrentDirectoryW(hInternetConnection, dir.c_str())) { DWORD lastError = GetLastError(); std::wcout << L"FtpSetCurrentDirectory error: " << lastError << std::endl; return files; } WIN32_FIND_DATAA win32FindData; HINTERNET hFind = FtpFindFirstFileA(hInternetConnection, "*.*", &win32FindData, INTERNET_FLAG_RESYNCHRONIZE, NULL); if (!hFind) { std::wcout << L"FtpFindFirstFile error: " << GetLastError() << std::endl; return files; } WCHAR buf[MAX_PATH] = L""; MultiByteToWideChar(CP_UTF8, 0, win32FindData.cFileName, sizeof(win32FindData.cFileName), buf, MAX_PATH); files.push_back(buf); while (InternetFindNextFileA(hFind, &win32FindData)) { MultiByteToWideChar(CP_UTF8, 0, win32FindData.cFileName, sizeof(win32FindData.cFileName), buf, MAX_PATH); files.push_back(buf); } InternetCloseHandle(hFind); return files; } int main() { _setmode(_fileno(stdout), _O_U16TEXT); _setmode(_fileno(stdin), _O_U16TEXT); _setmode(_fileno(stderr), _O_U16TEXT); std::wcout << L"Старт" << std::endl; HINTERNET hInternetRoot = InternetOpenW(L"Mozilla", INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, NULL); if (!hInternetRoot) { std::wcout << L"InternetOpen error: " << GetLastError() << std::endl; return 0; } HINTERNET hInternetConnection = InternetConnectW( hInternetRoot, L"server", INTERNET_DEFAULT_FTP_PORT, L"user", L"password", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, NULL ); if (!hInternetConnection) { std::wcout << L"InternetConnect error: " << GetLastError() << std::endl; InternetCloseHandle(hInternetRoot); return 0; } std::wstring command; WCHAR currentDir[MAX_PATH]; DWORD currentDirBuffer = MAX_PATH; if (!FtpGetCurrentDirectoryW(hInternetConnection, currentDir, ¤tDirBuffer)) { std::wcout << L"FtpGetCurrentDirectory error: " << GetLastError() << std::endl; return 0; } while (true) { std::wcout << L"FTP>"; WCHAR cmd[200] = L""; std::wcin.getline(cmd, 200); command.assign(cmd); if (command == L"scandir") { std::vector<std::wstring> files; int filesLen, i; files = scanDir(hInternetConnection, currentDir); filesLen = files.size(); for (i = 0; i < filesLen; i++) { std::wcout << files[i].c_str() << std::endl; } } else if (command == L"setdir") { } else if (command == L"exit") { return 0; } else { std::wcout << L"Invalid command" << std::endl; } std::wcout << std::endl; } return 0; }
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.