Hilfe! Boost::filesystem Exception handling!

stEEdZ

Mitglied
Hallo,
ich habe mit der Hilfe von Boost-Libraries ein Filesearch - Programm erstellt.
Das ganze soll dann später Plattformunabhängig laufen, deswegen auch kein Winapi.

Funktioniert übrigens auch sehr gut, mit nur einem Problem:
Wenn vom System der Zugriff auf bestimmte Ordner verweigert wird, bekommt man eine Exception reingeballert und das Programm terminiert!

Hier der Code:
PHP:
#include<boost/filesystem/operations.hpp>
#include<iostream>
#include<string>
#include <exception>
namespace bfs=boost::filesystem;

// Search for a file with the name 'filename' starting in directory 'dir_path', 
// copy the path of the file in 'pfound' if found, and return true.
// Else return false.
bool find_file(const bfs::path & dir_path, const std::string & file_name, bfs::path & pfound)
{
	if( !exists(dir_path) || !is_directory(dir_path) )
		return false;
	bfs::directory_iterator iter(dir_path), end_iter;
	for(; iter!= end_iter; ++iter)
	{
		if( bfs::is_directory(*iter) )
		{
			if( find_file(*iter, file_name, pfound) )
				return true;
		}
		else if( iter->leaf() == file_name )
		{
			pfound = *iter;
			std::cout<<pfound<<std::endl;
			return true;
		}
	}
	return false;
}

int main() { 
    bfs::path my_path("c:\\"); 
    bfs::path temp_path(""); 

    try { 
        if (!find_file(my_path,"test.cpp", temp_path)) 
            std::cout << "Konnte nicht gefunden werden!" << std::endl; 
    } 
    catch (std::exception const& e) { 
        std::cout << "EEEEERROR1elf" << std::endl; 
        std::cout << "type: " << typeid(e).name() << std::endl; 
        std::cout << "message: " << e.what() << std::endl; 
    } 
    system("pause"); 
}

Hier der Catch:
Code:
EEEEERROR1elf
type: class boost::filesystem::basic_filesystem_error<class boost::filesystem::b
asic_path<class std::basic_string<char,struct std::char_traits<char>,class std::
allocator<char> >,struct boost::filesystem::path_traits> >
message: boost::filesystem::basic_directory_iterator constructor: Zugriff verwei
gert: "c:\$Recycle.Bin\S-1-5-21-1829455090-3793272444-3375908254-500"
Drücken Sie eine beliebige Taste . . .

In einem anderem Forum wurde bei einem ähnlichem Thema dazu geraten, entweder die Exception zu fangen und zu ignorieren oder eine non-throwing Funktion zu verwenden oder eben die find_file Funktion umzubauen.

Ich bin hier leider total mit meinem Latein am Ende und hoffe auf Hilfe! :(
Danke im Vorraus
stEEdZ
 
Morgen,

wie dir schon geraten wurde, würde ich die find_file Funktion verändern, dort die Exception
zu catchen und zu irgnorieren. Ungefähr so:
C++:
for(; iter!= end_iter; ++iter) 
    {
        try {
            if(bfs::is_directory(*iter) ) 
            { 
                if( find_file(*iter, file_name, pfound) ) 
                    return true; 
            }
            else if( iter->leaf() == file_name ) 
            {
               pfound = *iter; 
                std::cout<<pfound<<std::endl; 
                return true; 
            } 
        } catch ( bsf::basic_filesystem_error &bfe ) {
        }
    }

So wird die Exception dann ignoriert und du hast mit den "access denied" keine
probleme mehr. Gegebenfalls überprüfen ob ein anderer Fehler als access denied
vorkommt und diesen handeln.

Best wishes
FBIagent
 
Zuletzt bearbeitet von einem Moderator:
Hi.

Du mußt die Rekursion nicht selbst programmieren. Nimm einfach den recursive_directory_iterator.

Bsp:
C++:
#include <iostream>

#include <cerrno>

#include <boost/filesystem.hpp>

using std::cout;
using std::cerr;
using std::endl;

using namespace boost::filesystem;

int main() {
  recursive_directory_iterator rdi("/etc");

  while (rdi != recursive_directory_iterator()) {
    cout << rdi->path() << endl;

    if (is_symlink(rdi->symlink_status())) {
      rdi.no_push();
    }

    do {
      try {
         ++rdi;
         break;
      } catch (const filesystem_path_error& e) {
         if (e.system_error() == EACCES) {
            cerr << "error: access denied [" << e.path1() << "]" << endl;
            rdi.no_push();
         } else {
            throw;
         }
      }
    } while (rdi != recursive_directory_iterator());
  }
}
Gruß
 
Hi,
vielen Dank für eure Hilfe!

@FBIagent:
Ich bekomme folgende 2 Fehlermeldungen:
Code:
error C2955: 'boost::filesystem::basic_filesystem_error' : use of class template requires template argument list
see declaration of 'boost::filesystem::basic_filesystem_error'
error C2316: 'boost::filesystem::basic_filesystem_error &' : cannot be caught as the destructor and/or copy constructor are inaccessible

Woran liegt das?


@deepthroat:
Wirklich sehr interessant! Danke! :)
Worin liegt der Vorteil des recursive_directory_iterator?

mfg
steedz
 
Zuletzt bearbeitet:
hab ich schon probiert :mad:

Da bekomm ich folgende Fehler:
Code:
error C2039: 'filesystem_path_error' : is not a member of 'boost::filesystem'
error C2061: syntax error : identifier 'filesystem_path_error'
error C2310: catch handlers must specify one type
error C2317: 'try' block starting on line '19' has no catch handlers


hier der Code
C++:
try{
			if( bfs::is_directory(*iter) )
			{
				if( find_file(*iter, file_name, pfound) )
					return true;
			}
			else if( iter->leaf() == file_name )
			{
				pfound = *iter;
				std::cout<<pfound<<std::endl;
				return true;
			}
		}
catch( bfs::filesystem_path_error &e  ){
}

Danke für die Hilfe
steedz
 
Zuletzt bearbeitet von einem Moderator:
hab ich schon probiert :mad:

Da bekomm ich folgende Fehler:
Code:
error C2039: 'filesystem_path_error' : is not a member of 'boost::filesystem'
error C2061: syntax error : identifier 'filesystem_path_error'
error C2310: catch handlers must specify one type
error C2317: 'try' block starting on line '19' has no catch handlers
Aha. Welche Boost Version verwendest du denn?

Gruß
 
Aha. Welche Boost Version verwendest du denn?

Gruß

boost_1_35_0, müsste die neueste sein oder?
Muss ich vielleicht noch nen extra Header einbinden?

So sehen meine Includes aus:
C++:
#include<boost/filesystem/operations.hpp>
#include<boost/filesystem.hpp>
#include<boost/utility.hpp>
#include<iostream>
#include<string>
#include <exception>
namespace bfs=boost::filesystem;

danke
 
Zurück