1

我正在尝试用 C++ 编写我的第一个程序,我需要使用 Boost 库。我正在尝试编写一个程序,它递归地遍历目录树并返回最新和最旧文件的日期。

这就是我现在的位置:

#define BOOST_FILESYSTEM_VERSION 3

#include "boost/filesystem.hpp"
#include <iostream>
#include <ctime>


using namespace std;
namespace fs = boost::filesystem;


int main() {
 fs::recursive_directory_iterator it_end;
 fs::recursive_directory_iterator it_dir("e:\\");
 fs::path p;

 time_t oldest( time(NULL) );
 time_t newest(0);

 try {
  for ( ; it_dir != it_end; ++it_dir ) {
   p = *it_dir;
   try {
    time_t t( last_write_time(p) );
    if (t<oldest) oldest=t;
    if (t>newest) newest=t;
    if (fs::is_directory(p)) cout << (p) << " " << t << endl;
   } 

   catch (const fs::filesystem_error& ex) {
    cout << "\n" << ex.what() << "\n";
   }
  }
 }

 catch (const fs::filesystem_error& ex) {
  cout << "\n" << ex.what() << "\n";
 }

 cout << "\nOldest: " << ctime(&oldest);
 cout << "Newest: " << ctime(&newest) << endl;

 return 0;
}

我遇到的问题是:

1.当我遇到路径太长(我认为超过256或260个字符)时,出现错误:

boost::filesystem::last_write_time: The system cannot find the path specified:

2.当我遇到一个不可访问的目录时,比如“系统卷信息”,我还有两个:

boost::filesystem::last_write_time: Access is denied: "e:\System Volume Information"

boost::filesystem::directory_iterator::construct: Access is denied: "e:\System Volume Information"

如何修改上面的代码以在 Windows 下处理长路径名?真的很难做到吗?一些程序,例如 Total Commander 没有长路径问题,但许多程序仍然存在。

更重要的问题是我如何才能真正使上述代码工作(不关心长路径)。问题是当for ( ; it_dir != it_end; ++it_dir )遇到一个不可访问的目录时,它会抛出一个异常,为了捕获这个异常,我需要定义外部捕获。但是当我在外面时,这意味着for循环没有继续。所以这意味着上面的代码可以工作到第一个不可访问的文件夹。它在那里引发异常并结束。

抛出异常后,有什么方法可以返回for循环? 我的想法是在 catch 内做一个 ++it_dir 并再次启动 for 循环。但是我怎样才能重新开始呢?Shell 我把它移出一个单独的函数?

对不起,如果我的理解不清楚,这是我的第一个项目。我以前从未使用过 C++,但我正在尽力而为!

编辑:

还有其他答案吗?问题是对于“不可访问”类型的错误,catch在循环内不起作用。我怎样才能让它在里面工作?这是产生错误的最小代码。有什么方法可以在 for 循环中捕获此错误?或者以在使用 it_dir++ 跳过不可访问元素后可以继续的方式捕获它?

int main() {
 fs::recursive_directory_iterator it_end;
 fs::recursive_directory_iterator it_dir("e:\\");

  for ( ; it_dir != it_end; ++it_dir ) {
  //something here
  }
}
4

2 回答 2

3

事实证明这是boost中的一个错误。我找到了一个错误支持票并为它做出了贡献。

于 2011-03-22T18:19:52.407 回答
0

只需将 try/catch 放在 for 循环中...

于 2010-11-24T01:04:22.483 回答