Różnice między wybraną wersją a wersją aktualną.
Both sides previous revision Previous revision Next revision | Previous revision | ||
filesystem [2008/04/16 22:38] michal.wasiak |
filesystem [2008/04/16 23:31] (aktualna) michal.wasiak |
||
---|---|---|---|
Linia 1: | Linia 1: | ||
====== Biblioteka boost::filesystem ====== | ====== Biblioteka boost::filesystem ====== | ||
- | __wersja robocza__ | + | **Michał Wasiak, //G1ISI//** |
===== Wstęp ===== | ===== Wstęp ===== | ||
Biblioteka boost::filesystem wprowadza przenośne udogodnienia w zarządzaniu ścieżkami dostępu do katalogów i plików. | Biblioteka boost::filesystem wprowadza przenośne udogodnienia w zarządzaniu ścieżkami dostępu do katalogów i plików. | ||
Linia 9: | Linia 10: | ||
* Programy używające tej biblioteki charakteryzuje pełna przenośność. Składnia, jak i zachowanie kodu programu są całkowicie niezależne od systemu operacyjnego. | * Programy używające tej biblioteki charakteryzuje pełna przenośność. Składnia, jak i zachowanie kodu programu są całkowicie niezależne od systemu operacyjnego. | ||
* Użycie biblioteki uważa się za bezpieczne, ponieważ ewentualne błędy nie mogą zostać zignorowane, gdyż większość funkcji zwraca wyjątki przy napotkaniu błędów. | * Użycie biblioteki uważa się za bezpieczne, ponieważ ewentualne błędy nie mogą zostać zignorowane, gdyż większość funkcji zwraca wyjątki przy napotkaniu błędów. | ||
+ | |||
===== Pliki nagłówkowe ===== | ===== Pliki nagłówkowe ===== | ||
- | * Nagłówek <[boost/filesystem.hpp]> wprowadza klasę //basic_path// i jej pochodne: //path// i //wpath//. Poza tym udostępnia wiele pomocnych operacji na plikach i katalogach. Klasa //basic_directory_iterator// umożliwia niezwykle użytczne iteracje po zawartości katalogów. | + | * Nagłówek ''<boost/filesystem.hpp>'' wprowadza klasę //basic_path// i jej pochodne: //path// i //wpath//. Poza tym udostępnia wiele pomocnych operacji na plikach i katalogach. Klasa //basic_directory_iterator// umożliwia niezwykle użytczne iteracje po zawartości katalogów. |
- | * Nagłowek <[boost/filesystem/fstream.hpp]> wprowadza takie same elementy co nagłówek //fstream// standardowej biblioteki C++, lecz same pliki są identyfikowane przez obiekty //basic_path//, a nie //char *s//. | + | * Nagłowek ''<boost/filesystem/fstream.hpp>'' wprowadza takie same elementy co nagłówek //fstream// standardowej biblioteki C++, lecz same pliki są identyfikowane przez obiekty //basic_path//, a nie //char *s//. |
===== Podstawowe klasy ===== | ===== Podstawowe klasy ===== | ||
+ | |||
==== basic_path ==== | ==== basic_path ==== | ||
+ | Obiekt klasy //path// może być stworzony w następujący sposób: | ||
+ | <code cpp> | ||
+ | path my_path("sciezka/plik.txt"); | ||
+ | </code> | ||
+ | String podawany jak argument może być ścieżką w ogólnym przenośnym formacie lub w natywnym formacie systemu operacyjnego. | ||
+ | |||
Klasa //path// posiada konstruktory konwersji z //const char*// i //std::string&//, więc pomimo tego, że biblioteka Filesystem używa parametru formalnego //path&// to i tak dozwolone jest podawanie jako parametrów napisów w stylu C: | Klasa //path// posiada konstruktory konwersji z //const char*// i //std::string&//, więc pomimo tego, że biblioteka Filesystem używa parametru formalnego //path&// to i tak dozwolone jest podawanie jako parametrów napisów w stylu C: | ||
<code cpp> | <code cpp> | ||
Linia 25: | Linia 35: | ||
</code> | </code> | ||
Ścieżki mogą zawierać odwołanie do bieżącego katalogu używając notacji ".", a także do nadkatalogu, używając zapisu "..". | Ścieżki mogą zawierać odwołanie do bieżącego katalogu używając notacji ".", a także do nadkatalogu, używając zapisu "..". | ||
+ | |||
+ | |||
Linia 34: | Linia 46: | ||
bool find_file( const bf::path& dir_path, | bool find_file( const bf::path& dir_path, | ||
- | const std::string& file_name, | + | const std::string& file_name, |
- | path& path_found ) { | + | path& path_found ) { |
- | if(!exists(dir_path) || !is_directory(dir_path)) | + | if(!exists(dir_path) || !is_directory(dir_path)) |
- | return false; | + | return false; |
- | directory_iterator iter(dir_path), end_iter; | + | directory_iterator iter(dir_path), end_iter; |
- | for(; iter != end_iterl ++iter) { | + | for(; iter != end_iterl ++iter) { |
- | if(bf::is_directory(*iter)) { | + | if(bf::is_directory(*iter)) { |
- | if(find_file(*iter, file_name, path_found)) | + | if(find_file(*iter, file_name, path_found)) |
- | return true; | + | return true; |
- | } | + | |
- | else if(iter->leaf() == file_name) { | + | |
- | path_found = *iter; | + | |
- | return true; | + | |
- | } | + | |
} | } | ||
- | return false; | + | else if(iter->leaf() == file_name) { |
+ | path_found = *iter; | ||
+ | return true; | ||
+ | } | ||
+ | } | ||
+ | return false; | ||
} | } | ||
</code> | </code> | ||
Funkcja najpierw sprawdza czy podana ścieżka w //path_dir// istnieje i jest katalogiem. Później tworzy obiekt //directory_iterator// podając ściężkę do konstruktora. Pętla iteruje po wszystkich elementach katalogu i dla każdego napotkanego podkatalogu wywołuje rekursywnie funkcję szukającą. Każdy rozpoznany plik jest porównywany co do nazwy z paramatrem //file_name// i jeśli znaleziony zostanie plik o podanej nazwie to do //path_found// kopiowana jest scieżka do tego pliku i zwracana jest wartość 'true'. Jeśli nic nie zostanie znalezione to zwrcana jest wartość 'false'. | Funkcja najpierw sprawdza czy podana ścieżka w //path_dir// istnieje i jest katalogiem. Później tworzy obiekt //directory_iterator// podając ściężkę do konstruktora. Pętla iteruje po wszystkich elementach katalogu i dla każdego napotkanego podkatalogu wywołuje rekursywnie funkcję szukającą. Każdy rozpoznany plik jest porównywany co do nazwy z paramatrem //file_name// i jeśli znaleziony zostanie plik o podanej nazwie to do //path_found// kopiowana jest scieżka do tego pliku i zwracana jest wartość 'true'. Jeśli nic nie zostanie znalezione to zwrcana jest wartość 'false'. | ||
- | ===== Gramatyka? ===== | + | |
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== Formaty ścieżek ===== | ||
+ | Są dwa formaty łańcuchów opisujących ścieżkę dostępu: | ||
+ | * Przenośny format opisany przez POSIX; | ||
+ | * Natywny format ścieżki dostępu definiowany przez system operacyjny. Przykłady:\\ //OpenVMS:// ''"SYS1::DISK1:[DANE.FILMY]"''\\ //Windows:// ''"c:\dane\filmy"'' | ||
+ | |||
Linia 69: | Linia 93: | ||
void rename(const Path1& from_p, const Path2& to_p); | void rename(const Path1& from_p, const Path2& to_p); | ||
</code> | </code> | ||
- | Funkcja zmienia nazwę pliku //from_fp// na nową //to_p/// | + | Funkcja zmienia nazwę pliku //from_fp// na nową //to_p//. |
<code cpp> | <code cpp> | ||
bool remove(const Path& p); | bool remove(const Path& p); | ||
Linia 93: | Linia 117: | ||
template <class Path> typename Path::string_type extension(const Path & p); | template <class Path> typename Path::string_type extension(const Path & p); | ||
</code> | </code> | ||
- | Funkcja zwracająca rozszerzenie pliku. Jeśli ''p.leaf()'' zawiera kropkę, to funkcja zwraca podciąg z ''p.leaf()'' zaczynający się od ostatniej kropki aż do ostatniego znaku nazwy. W przeciwnym razie wypadku zwraca pusty łańcuch. | + | Funkcja zwracająca rozszerzenie pliku. Jeśli ''p.leaf()'' zawiera kropkę, to funkcja zwraca podciąg z ''p.leaf()'' od ostatniej kropki aż do ostatniego znaku nazwy. W przeciwnym razie zwraca pusty łańcuch. |
<code cpp> | <code cpp> | ||
template <class Path> typename Path::string_type basename(const Path & p); | template <class Path> typename Path::string_type basename(const Path & p); | ||
</code> | </code> | ||
- | Funkcja zwracająca nazwę pliku bez rozszerzenia. Jeśli ''p.leaf()'' zawiera kropkę, to funkcja zwraca podciąg z ''p.leaf()'' zaczynający się od początku nazwy do ostatniej kropki (kropka nie jest zawarta). W przeciwnym wypadku zwraca ''p.leaf()''.<code cpp> | + | Funkcja zwracająca nazwę pliku bez rozszerzenia. Jeśli ''p.leaf()'' zawiera kropkę, to funkcja zwraca podciąg z ''p.leaf()'' od początku nazwy do ostatniej kropki (kropka nie jest zawarta). W przeciwnym wypadku zwraca ''p.leaf()''. |
+ | <code cpp> | ||
template <class Path> Path replace_extension(const Path & p, const typename Path::string_type & new_extension); | template <class Path> Path replace_extension(const Path & p, const typename Path::string_type & new_extension); | ||
</code> | </code> | ||
Funkcja zmienia rozszerzenie pliku //p// na nowe //new_extension//. | Funkcja zmienia rozszerzenie pliku //p// na nowe //new_extension//. | ||
+ | |||
Linia 110: | Linia 136: | ||
void listing(const bf::path& p) { | void listing(const bf::path& p) { | ||
- | unsigned long dir_count = 0; | + | unsigned long dir_count = 0; |
- | unsigned long file_count = 0; | + | unsigned long file_count = 0; |
- | unsigned long other_count = 0; | + | unsigned long other_count = 0; |
- | unsigned long err_count = 0; | + | unsigned long err_count = 0; |
- | if(!bf::exists(p)) { | + | if(!bf::exists(p)) { |
- | std::cout << "Nieprawidlowa sciezka: " << p.native_file_string() << std::endl; | + | std::cout << "Nieprawidlowa sciezka: " << p.native_file_string() << std::endl; |
- | return; | + | return; |
- | } | + | } |
- | if(bf::is_directory(p)) { | + | if(bf::is_directory(p)) { |
- | std::cout << "W katalogu: " << p.native_file_string() << "\n\n"; | + | std::cout << "W katalogu: " << p.native_file_string() << "\n\n"; |
- | bf::directory_iterator iter(p), end_iter; | + | bf::directory_iterator iter(p), end_iter; |
- | for(; iter != end_iter; ++iter) { | + | for(; iter != end_iter; ++iter) { |
- | try { | + | try { |
- | if(bf::is_directory(*iter)) { | + | if(bf::is_directory(*iter)) { |
- | ++dir_count; | + | ++dir_count; |
- | std::cout << iter->leaf() << " [katalog]\n"; | + | std::cout << iter->leaf() << " [katalog]\n"; |
- | } | + | } |
- | else if(fs::is_regular(iter->status())) { | + | else if(fs::is_regular(iter->status())) { |
- | ++file_count; | + | ++file_count; |
- | std::cout << iter->leaf() << " (" << bf::file_size(*iter) <<" B)\n"; | + | std::cout << iter->leaf() << " (" << bf::file_size(*iter) <<" B)\n"; |
- | } | + | } |
- | else { | + | else { |
- | +other_count; | + | ++other_count; |
- | std::cout << iter->leaf() << " [inny]\n"; | + | std::cout << iter->leaf() << " [inny]\n"; |
- | } | + | } |
- | } catch(const std::exception& ex) { | + | } catch(const std::exception& ex) { |
- | ++err_count; | + | ++err_count; |
- | std::cout << iter->leaf() << ": " << ex.what() << std::endl; | + | std::cout << iter->leaf() << ": " << ex.what() << std::endl; |
- | } | + | } |
- | } | + | } |
- | std::cout << std::endl << file_count << " plikow\n" | + | std::cout << std::endl << file_count << " plikow\n" |
- | << dir_count << " katalogow\n" | + | << dir_count << " katalogow\n" |
- | << other << " innych\n" | + | << other << " innych\n" |
- | << err_count << " błedów\n"; | + | << err_count << " błedów\n"; |
- | } | + | } |
- | else { // musi byc plikiem | + | else { // musi byc plikiem |
- | std::cout << "Plik: " << p.native_file_string() << std::endl; | + | std::cout << "Plik: " << p.native_file_string() << std::endl; |
- | } | + | } |
} | } | ||
</code> | </code> |