【问题标题】:cpp: error when using rename functioncpp:使用重命名功能时出错
【发布时间】:2014-05-18 14:45:33
【问题描述】:

我有以下代码:

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: 这是同步代码,以防万一:

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:是的,路径确实匹配。 filePaths 中的“...”是出于隐私原因。

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

编辑:第一个 rvParam(“REN”)将在创建 CommandRenHandler 的工厂类中删除。在那里,将调用 HandleCommand 函数,并删除第一个 rvParam(在本例中为“REN”)。所以 rvParams.at(0) 是第一个文件路径,而 rvParams.at(1) 是第二个文件路径。

抱歉,我之前在代码中没有提到这一点。

【问题讨论】:

  • renamenewname 部分再次尝试不使用完整路径。 MSDN 文档针对各种情况发出警告,但在这一点上有点不清楚。对了,查一下errno——它提供了比-1更清晰的错误描述。
  • 您是否要重命名为已存在的文件?如果是这样,您可能需要在使用rename之前删除现有的目标文件...
  • @Jongware 我在没有完整路径的情况下尝试了它,但它仍然给出了相同的错误。我还添加了 errno 并返回 nr。 13.
  • @KevinCruijssen 在从同步调用重命名之前文件是否在任何地方打开,也许?
  • @NemanjaBoric Nvm.. 我还在另一个地方打开了文件。我确实有关闭它的代码,但由于之前的返回语句,我没有结束。

标签: c++ windows sockets sync rename


【解决方案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");
    }
}

【讨论】:

  • 虽然在我发布的代码中看不到,但第一个参数将在工厂类中删除。所以它是带有 REN、filePath 和 filePath2 的 rvParams(然后它在工厂中制作了 CommandRenHandler 并删除了 REN)。对不起,我没有在我的代码中说清楚..
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 2017-03-27
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多