c++ wininet ftp 列出许多文件错误
c++ wininet ftp listing many files bug
我正在使用 wininet 连接到服务器。
一切正常,上传,下载,列出命令等......
因此,我有一个小错误,我不知道它来自哪里。
错误是某些包含超过 100 个文件(e.x. 的图像)的服务器文件夹并未全部列出,据我测试,该列表仅在任何文件夹中的 91 个文件之前响应,超过该数量无法显示或看到。
这是我的代码的一部分,我使用 list -la 选项列出文件夹以查看服务器上的所有文件
// Get Current Directory
DWORD FTPdirsize = MAX_PATH + 8;
TCHAR FTPcurDir[MAX_PATH + 8];
if (FtpGetCurrentDirectory(FTPsession, FTPcurDir, &FTPdirsize) == TRUE){
HINTERNET FTPcommandRecVal;
BOOL FTPres = FtpCommand(FTPsession, TRUE, FTP_TRANSFER_TYPE_BINARY, FTPsearchParam, NULL, &FTPcommandRecVal);
if (FTPres && FTPcommandRecVal){
DWORD dwRead;
char szBuf[8192];
string FullStrBuf;
while (InternetReadFile(FTPcommandRecVal, szBuf, 8192, &dwRead) && dwRead != 0){
FullStrBuf = szBuf;
FullStrBuf = FullStrBuf.substr(0, dwRead);
}
InternetCloseHandle(FTPcommandRecVal);
int nIdx = 0;
char szLine[8192] = { 0 };
char c;
int TheEndLenght = FullStrBuf.length();
for (int i = 0; i < TheEndLenght - 1; i++){
c = FullStrBuf[i];
if (c == '\r' || c == '\n' || c == '[=11=]'){
if (nIdx){
struct ftpparse fp;
int nRes = ftpparse(&fp, szLine, nIdx);
if (nRes){
// Name
wstring FTPsrvFFnameW = fp.strName;
FTPList.push_back(FTPsrvFFnameW);
}
}
for (int j = 0; j < sizeof(szLine); j++){
szLine[j] = 0;
}
nIdx = 0;
}
else{
szLine[nIdx++] = c;
}
}
////... print function for FTPList
}
else{
InternetCloseHandle(FTPcommandRecVal);
/////... ERROR HANDLING
}
}
else{
/////... ERROR HANDLING
}
请注意,我使用的是 4096 缓冲区而不是 8192,并且它只列出了文件夹中所有文件中的 37 个文件。
我将其更改为 8192,它列出了 91 个文件,高于 8192 的任何其他值与我的测试相同,所以我想一定还有其他东西不允许正确列出所有文件并且有限制。
服务器也没有限制通过 ftp 个客户端列出文件。
我也用这个ftp解析这个link
https://cr.yp.to/ftpparse.html
非常感谢解决此错误的任何帮助。
调用FullStrBuf = szBuf;
后FullStrBuf
中的旧信息丢失,改用:
while (InternetReadFile(FTPcommandRecVal, szBuf, 8192, &dwRead) && dwRead != 0)
{
FullStrBuf.append(szBuf, dwRead);
}
建议:
如果FullStrBuf
中间没有'[=15=]'
,可以用std::find
或std::find_first_of
来打断字符串。例如,假设 FullStrBuf
包含 "\n"
或 "\r\n"
换行:
for(size_t start = 0, pos = 0; pos != string::npos;)
{
pos = FullStrBuf.find_first_of("\r\n", start);
string s = FullStrBuf.substr(start, pos - start);
if(s.size())
{
cout << s << endl;
//ftpparse ...
}
start = pos + 1;
}
我正在使用 wininet 连接到服务器。 一切正常,上传,下载,列出命令等...... 因此,我有一个小错误,我不知道它来自哪里。 错误是某些包含超过 100 个文件(e.x. 的图像)的服务器文件夹并未全部列出,据我测试,该列表仅在任何文件夹中的 91 个文件之前响应,超过该数量无法显示或看到。
这是我的代码的一部分,我使用 list -la 选项列出文件夹以查看服务器上的所有文件
// Get Current Directory
DWORD FTPdirsize = MAX_PATH + 8;
TCHAR FTPcurDir[MAX_PATH + 8];
if (FtpGetCurrentDirectory(FTPsession, FTPcurDir, &FTPdirsize) == TRUE){
HINTERNET FTPcommandRecVal;
BOOL FTPres = FtpCommand(FTPsession, TRUE, FTP_TRANSFER_TYPE_BINARY, FTPsearchParam, NULL, &FTPcommandRecVal);
if (FTPres && FTPcommandRecVal){
DWORD dwRead;
char szBuf[8192];
string FullStrBuf;
while (InternetReadFile(FTPcommandRecVal, szBuf, 8192, &dwRead) && dwRead != 0){
FullStrBuf = szBuf;
FullStrBuf = FullStrBuf.substr(0, dwRead);
}
InternetCloseHandle(FTPcommandRecVal);
int nIdx = 0;
char szLine[8192] = { 0 };
char c;
int TheEndLenght = FullStrBuf.length();
for (int i = 0; i < TheEndLenght - 1; i++){
c = FullStrBuf[i];
if (c == '\r' || c == '\n' || c == '[=11=]'){
if (nIdx){
struct ftpparse fp;
int nRes = ftpparse(&fp, szLine, nIdx);
if (nRes){
// Name
wstring FTPsrvFFnameW = fp.strName;
FTPList.push_back(FTPsrvFFnameW);
}
}
for (int j = 0; j < sizeof(szLine); j++){
szLine[j] = 0;
}
nIdx = 0;
}
else{
szLine[nIdx++] = c;
}
}
////... print function for FTPList
}
else{
InternetCloseHandle(FTPcommandRecVal);
/////... ERROR HANDLING
}
}
else{
/////... ERROR HANDLING
}
请注意,我使用的是 4096 缓冲区而不是 8192,并且它只列出了文件夹中所有文件中的 37 个文件。 我将其更改为 8192,它列出了 91 个文件,高于 8192 的任何其他值与我的测试相同,所以我想一定还有其他东西不允许正确列出所有文件并且有限制。 服务器也没有限制通过 ftp 个客户端列出文件。
我也用这个ftp解析这个link https://cr.yp.to/ftpparse.html
非常感谢解决此错误的任何帮助。
调用FullStrBuf = szBuf;
后FullStrBuf
中的旧信息丢失,改用:
while (InternetReadFile(FTPcommandRecVal, szBuf, 8192, &dwRead) && dwRead != 0)
{
FullStrBuf.append(szBuf, dwRead);
}
建议:
如果FullStrBuf
中间没有'[=15=]'
,可以用std::find
或std::find_first_of
来打断字符串。例如,假设 FullStrBuf
包含 "\n"
或 "\r\n"
换行:
for(size_t start = 0, pos = 0; pos != string::npos;)
{
pos = FullStrBuf.find_first_of("\r\n", start);
string s = FullStrBuf.substr(start, pos - start);
if(s.size())
{
cout << s << endl;
//ftpparse ...
}
start = pos + 1;
}