cpp:使用重命名功能时出错

时间:2014-04-06 12:36:07

标签: c++ windows sockets sync rename

我有以下代码:

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");
}

在这个函数中,我收到两个文件路径,其中包含需要重命名的文件。我添加了TEST cout。

我有1个需要重命名的文件。以下是我的测试的输入和输出:

1(手动重命名文件 - 按意图工作):

在控制台中:

REN one\image.png one\new_image.png

调试:

filePath = "C:\\...\\one\\image.png"
filePath2 = "C:\\...\\one\\new_image.png"
result = 0;

测试输出:

C:\...\one\image.png C:\...\one\new_image.png result: 0

2(手动重命名文件 - 按意图工作):

在控制台中:

REN one\new_image.png one\image.png

调试:

filePath = "C:\\...\\one\\new_image.png"
filePath2 = "C:\\...\\one\\image.png"
result = 0;

测试输出:

C:\...\one\new_image.png C:\...\one\image.png result: 0

3(使用相同重命名的SYNC - 不工作):

在控制台中:

SYNC one one

(此方法检查文件是否已更改或仅重命名。在这种情况下,它会重命名,并将下面的信息发送到重命名功能,就像上面的常规REN一样。)

调试:

filePath = "C:\\...\\one\\image.png"
filePath2 = "C:\\...\\one\\new_image.png"
result = -1;

测试输出:

C:\...\one\image.png C:\...\one\image.png result: -1

1(再次重命名同一个文件,与步骤1中的完全相同,但这次我们再次收到错误 - 不再进行任何操作)

在控制台中:

REN one\image.png one\new_image.png

调试:

filePath = "C:\\...\\one\\image.png"
filePath2 = "C:\\...\\one\\new_image.png"
result = -1;

测试输出:

C:\...\one\image.png C:\...\one\new_image.png result: -1

所以,我的问题是:为什么C ++的重命名功能最初工作正常,但在SYNC功能期间失败,之后我也不能再手动使用REN功能..

TL; DR:有人能看到提供的代码部分存在什么问题吗?或者有什么方法可以查看导致重命名错误的原因吗?因为只有-1作为调试结果有点无用。

提前致谢。

PS: 这是SYNC代码,以防万一:

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:是的,路径完全匹配。 &#34; ...&#34;在filePaths中是出于隐私原因。

对于那些想知道的人:C ++是用Windows编写的,而不是Linux编码。

编辑:第一个rvParam(&#34; REN&#34;)将在工厂类中删除,这将创建CommandRenHandler。在那里将调用HandleCommand函数,并删除第一个rvParam(在这种情况下为&#34; REN&#34;)。所以rvParams.at(0)是第一个filePath,rvParams.at(1)是第二个filePath。

很抱歉,在我的代码之前我没有提到过。

2 个答案:

答案 0 :(得分:1)

嗯,你有一个错误:

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");
    }
}

答案 1 :(得分:1)

在Nemanja Boric的提示之后,文件可能仍在某处打开,我查看了我的代码。事实证明我仍然有一个ifstream打开(但这不是问题,因为关闭它后仍然会出现同样的问题)。

然后我继续寻找并注意到我没有在我的代码中的其他地方关闭另一个流,因为早期的返回声明。

TL; DR:必须在我的代码中关闭一个开放的流才能重命名该文件。