我有以下代码:
void CommandRenHandler::HandleCommand(Socket* socket, std::vector<std::string>& rvParams){
if (rvParams.size() < 2){
socket->writeline("Not enough parameters specified");
return;
}
std::string filePath = BASE_DIRECTORY;
filePath.append(rvParams.at(0));
std::string filePath2 = BASE_DIRECTORY;
filePath2.append(rvParams.at(1));
int result = rename(filePath.c_str(), filePath2.c_str());
// TEST
std::cout << filePath << " " << filePath2 << std::endl << "result: " << result << std::endl;
if (result == 0)
socket->writeline("File renamed");
else
socket->writeline("Could not rename file");
}
在此函数中,我收到两个文件路径,其中包含需要重命名的文件。我已经添加了测试库特。
我有 1 个文件需要重命名。以下是我的测试的输入和输出:
1(手动重命名文件 - 按预期工作):
在控制台中:
REN oneimage.png onenew_image.png
调试:
filePath = "C:\...\one\image.png"
filePath2 = "C:\...\one\new_image.png"
result = 0;
测试输出:
C:...oneimage.png C:...onenew_image.png result: 0
2(手动重命名文件 - 按预期工作):
在控制台中:
REN onenew_image.png oneimage.png
调试:
filePath = "C:\...\one\new_image.png"
filePath2 = "C:\...\one\image.png"
result = 0;
测试输出:
C:...onenew_image.png C:...oneimage.png result: 0
3(使用使用相同的重命名的 SYNC - 不起作用):
在控制台中:
SYNC one one
(此方法检查文件是否已更改或刚刚重命名。在这种情况下,它被重命名,它会将以下信息发送到重命名函数,就像上面的常规 REN 一样。
调试:
filePath = "C:\...\one\image.png"
filePath2 = "C:\...\one\new_image.png"
result = -1;
测试输出:
C:...oneimage.png C:...oneimage.png result: -1
1(再次重命名相同的文件,与步骤 1 完全相同,但这次我们也再次收到错误 - 不再工作)
在控制台中:
REN oneimage.png onenew_image.png
调试:
filePath = "C:\...\one\image.png"
filePath2 = "C:\...\one\new_image.png"
result = -1;
测试输出:
C:...oneimage.png C:...onenew_image.png result: -1
所以,我的问题是:为什么C++的重命名功能一开始工作正常,但在 SYNC 功能期间失败,之后我也无法再手动使用 REN 函数。
TL;DR:有人能看到仅提供的代码部分的问题是什么吗?或者有什么方法可以查看导致重命名错误的原因?因为只有 -1 作为调试结果有点没用。.
提前谢谢。
附注:这是同步代码,以防万一:
std::vector<std::string> vParams;
// Check wether file is completely different or just renamed
std::string oldFile = FileJustRenamed(file);
if (oldFile != "") {
vParams.push_back(std::string("REN"));
vParams.push_back(oldFile);
vParams.push_back(file);
std::cout << "Renaming " << file << std::endl;
ren_handler->HandleCommand(socket, vParams);
}
PSS:是的,路径确实完全匹配。"..."在文件中路径是出于隐私原因。
对于那些想知道的人:C++是用Windows而不是Linux编码的。
编辑:第一个rvParam("REN")将在工厂类中删除,这将创建CommandRenHandler。在那里,将调用 HandleCommand 函数,并删除第一个 rvParam(在本例中为"REN")。所以 rvParams.at(0)是第一个filePath,rvParams.at(1)是第二个filePath。
抱歉,我之前在我的代码中没有提到这一点。
好吧,您有一个错误:
if (oldFile != "") {
vParams.push_back(std::string("REN"));
vParams.push_back(oldFile);
vParams.push_back(file);
std::cout << "Renaming " << file << std::endl;
ren_handler->HandleCommand(socket, vParams);
}
在这里,vParams.at(0)
"REN"
字符串,您在rename
中使用:
std::string filePath = BASE_DIRECTORY;
filePath.append(rvParams.at(0)); // THIS IS "REN" and not the actual filename.
std::string filePath2 = BASE_DIRECTORY;
filePath2.append(rvParams.at(1));
int result = rename(filePath.c_str(), filePath2.c_str());
所以,根据我所看到的,我想这是HandleCommand
的正确实现:
void CommandRenHandler::HandleCommand(Socket* socket, std::vector<std::string>& rvParams){
if (rvParams.size() < 3){
socket->writeline("Not enough parameters specified");
return;
}
if(rvParams.at(0) == "REN")
{
std::string filePath = BASE_DIRECTORY;
filePath.append(rvParams.at(1));
std::string filePath2 = BASE_DIRECTORY;
filePath2.append(rvParams.at(2));
int result = rename(filePath.c_str(), filePath2.c_str());
// TEST
std::cout << filePath << " " << filePath2 << std::endl << "result: " << result << std::endl;
if (result == 0)
socket->writeline("File renamed");
else
socket->writeline("Could not rename file");
}
}
在Nemanja Boric的提示之后,文件可能仍然在某个地方打开,我查看了我的代码。事实证明,我仍然打开了一个ifstream(但这不是问题所在,因为关闭它后仍然会出现同样的问题)。
然后我继续寻找,注意到我没有在我的代码中的其他地方关闭另一个流,因为早期的返回语句。
TL;DR:必须关闭代码中的开放流才能重命名文件。