最初のプログラムを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.「システムボリューム情報」などのアクセスできないディレクトリに遭遇すると、さらに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サイクルを再開することです。しかし、どうすれば再開できますか?シェル別の機能に移動しますか?
私の理解がはっきりしない場合は申し訳ありませんが、それは私の最初のプロジェクトです。これまでC++を使用したことはありませんが、最善を尽くしています。
編集:
他に答えはありますか?問題は、「アクセスできない」種類のエラーのサイクル内でキャッチが機能していないことです。どうすれば内部で機能させることができますか?これがエラーを生成する最小のコードです。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
}
}