在C++中查找和移动文件

two*_*ung 3 c++

我是新手C++,我刚看完<C++ Primer> 4ed.现在我想实现一个小程序来帮助我管理mp3计算机中的一些文件.

我有一个.txt文件,其中包含我要移动(不复制)到新文件夹(在同一列中)的文件的所有名称(实际名称的一部分).例如,"word"和"file"中的.txt和我想将.mp3文件名包含"word"或"file"的所有文件移动到新文件夹中.希望我的描述清楚,Opps ..

我知道如何将字符串读.txtset<string>并遍历它,但我不知道如何搜索和移动文件夹中的文件.我只想知道我还应该学习什么才能实现这个功能.我读了C++ Primer但仍然做不了多少事,真的很难过......

Phi*_*ßen 9

要使用C++移动文件,您不必使用Boost.Filesystem等外部库,但可以使用标准功能.

有新的文件系统API,它具有重命名功能:

#include <iostream>
#include <filesystem>

int main() {
  try {
    std::filesystem::rename("from.txt", "to.txt");
  } catch (std::filesystem::filesystem_error& e) {
    std::cout << e.what() << '\n';
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

缺点是编译它,你需要一个最新的C++ 17编译器.(我在gcc 8.0.1上测试过,我也需要链接-lstdc++fs).

但是今天在任何C++编译器上应该起作用的是旧的C API,它还提供了重命名(cstdio):

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cerrno>

int main() {
  if(std::rename("from.txt", "to.txt") < 0) {
    std::cout << strerror(errno) << '\n';
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

但请注意,在这两种情况下,如果源文件系统和目标文件不在同一文件系统上,则重命名将失败.然后你会看到这样的错误:

filesystem error: cannot rename: Invalid cross-device link [from.txt] [/tmp/to.txt]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您只能制作副本然后删除原始文件:

#include <fstream>
#include <iostream>
#include <ios>
#include <cstdio>

int main() {
  std::ifstream in("from.txt", std::ios::in | std::ios::binary);
  std::ofstream out("to.txt", std::ios::out | std::ios::binary);
  out << in.rdbuf();
  std::remove("from.txt");
}
Run Code Online (Sandbox Code Playgroud)

或者使用新的API:

#include <iostream>
#include <filesystem>

int main()
{
  try {
    std::filesystem::copy("from.txt", "to.txt");
    std::filesystem::remove("from.txt");
  } catch (std::filesystem::filesystem_error& e) {
    std::cout << e.what() << '\n';
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • @AlexanderDyagilev 如果您查看“重命名”系统调用的文档,您会发现跨不同文件系统重命名会导致 EXDEV 错误。至少在 POSIX 系统上,您不能假设重命名在这种情况下会起作用。来源:http://man7.org/linux/man-pages/man2/rename.2.html (3认同)

Seb*_*ann 1

仅使用 std 才能实现此操作的唯一方法是使用 a 完全读取文件std::ifstream,然后使用 a 将其写入新位置std::ofstream。但是,这不会从磁盘中删除旧文件。所以基本上您创建了该文件的副本。它也比真正的移动慢得多。

最佳解决方案是使用操作系统特定的 API,例如 win32,它提供MoveFile()函数。Poco 提供了此类 API 的独立于平台的抽象。请参阅: http: //www.appinf.com/docs/poco/Poco.File.html