【问题标题】:Moving files from one directory into another将文件从一个目录移动到另一个目录
【发布时间】:2017-07-20 23:48:50
【问题描述】:

我想将所有文件从 test1 复制到 test2。代码编译但没有任何反应。

#include <iostream>
#include <stdlib.h>
#include <windows.h>

using namespace std;

int main()
{
    string input1 = "C:\\test1\\";
    string input2 = "C:\\test2\\";
    MoveFile(input1.c_str(), input2.c_str());
}

我正在考虑 xcopy 但它不接受预定义的字符串。有解决办法吗?

【问题讨论】:

  • 检查MoveFile的返回值,当你看到它说失败时,使用GetLastError找出原因。
  • 根据MoveFile() 文档:“lpNewFileName [in] 文件或目录的新名称。新名称不得已存在。A新文件可能位于不同的文件系统或驱动器上。新目录必须位于同一驱动器上。" test2 目录是否已存在?考虑使用SHFileOperation()IFileOperation 而不是MoveFile()
  • 如果这两个都是目录,那么你希望发生的事情就不会发生。

标签: c++ winapi


【解决方案1】:
std::string GetLastErrorAsString()
{
    //Get the error message, if any.
    DWORD errorMessageID = ::GetLastError();
    if (errorMessageID == 0)
        return std::string(); //No error message has been recorded

    LPSTR messageBuffer = nullptr;
    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

    std::string message(messageBuffer, size);

    //Free the buffer.
    LocalFree(messageBuffer);

    return message;
}
int main()
{
    string input1 = "C:\\test1\\";
    string input2 = "C:\\test2\\";
    if (!MoveFile(input1.c_str(), input2.c_str()))
    {
        string msg = GetLastErrorAsString(); 
        cout << "fail: " << msg << endl;
    }
    else {
        cout << "ok" << endl;
    }
    system("pause");
}

您的代码适用于我,您可能需要在项目属性中将字符集设置为 use multi-byte character set。 如果没有,请向我们提供错误。 检查您是否具有对 C: 的写入权限。 检查 C: 中是否已有 test2 文件夹(或者 C: 中是否没有 test1 文件夹)。

【讨论】:

  • GetLastErrorAsString() 泄漏内存以防std::string c'tor 引发异常。它也很晚才调用GetLastError()。一个更好的实现已经发布在this documentation topic
  • 另外,写入std::cout 可能会间接导致GetLastError() 重置。如果MoveFile() 成功,调用GetLastError() 是没有意义的。仅当 MoveFile() 失败时,您必须调用 GetLastError(),并且必须在调用任何其他 Win32 API 函数之前调用,例如:if (!MoveFile(input1.c_str(), input2.c_str())) { string msg = GetLastErrorAsString(); cout &lt;&lt; "fail: " &lt;&lt; msg &lt;&lt; endl; } else { cout &lt;&lt; "ok" &lt;&lt; endl; }
  • @RemyLebeau 感谢您指出这一点,我用它编辑了答案
  • @IInspectable 好点,我查看了您的链接,肯定会用它更新这个答案(以及我自己的 GetLastError 函数)(但很可能是明天)
  • 我会使用简单的std::vector 甚至是固定大小的数组,而不是带有自定义删除器的std::unique_ptr。您不必让FormatMessage() 分配缓冲内存。但如果你这样做了,你可以use LocalFree() directly as the deleter(即使在 Windows 10 上,尽管文档中有警告)。您无需使用 lambda 来委托给 HeapFree()
【解决方案2】:

我通过从 test2 中删除 \\ 解决了这个问题。文件夹 test 2 不存在。感谢您的回复和测试代码。我认为 SHFileOperation 将是一个更好的选择,因为我必须将文件从软盘传输到我的 C 驱动器。字符串 input1 = "C:\\test1\\"; string input2 = "C:\\test2";

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 2014-12-04
    • 2021-11-12
    • 2016-06-09
    • 2016-04-04
    • 1970-01-01
    相关资源
    最近更新 更多