namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:include:filesystem

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


kennen:include:filesystem [2020-01-04 16:37] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== <filesystem> ======
 +Diese Bibliothek erlaubt weitgehend systemunabhängigen Zugriff auf das Dateisystem.
 +Für eine umfassende, detailliertere Beschreibung siehe [[cppref>cpp/filesystem|<filesystem>]].
 +Hier folgen eher Anwendungsbeispiele.
 +===== Einbinden =====
 +Vor der Integration in C++17 wurde zunächst Filesystem TS veröffentlicht. 
 +Notfalls kann auf diese Version zurückgegriffen werden:
 +<code cpp>
 +#if __has_include(<filesystem>)
 +  #include <filesystem>
 +  namespace fs = std::filesystem;
 +#elif __has_include(<experimental/filesystem>)
 +  #include <experimental/filesystem>
 +  namespace fs = std::experimental::filesystem;
 +  // g++ : link with -lstdc++fs
 +#else
 +  #error No filesystem library.
 +#endif
 +</code>
 +
 +===== Pfade =====
 +Ein Pfad ''fs::path'' beschreibt den Weg zu einer Datei im Dateisystem absolut zur Wurzel oder relativ zu ''fs::current_path()''
 +Er besteht aus
 +  * einem optionalen ''p.root_name()'' --- unter Windows ein Laufwerk ''C:'' oder ''%%//server%%'',
 +  * einem optionalen ''p.root_directory()'' -- je nach Betriebsystem ''/'' oder ''\'',
 +  * und weiteren Namen, die --- bis auf den letzten --- Namen von Verzeichnissen sein müssen.
 +
 +Dabei sind Verzeichnisse ebenfalls Dateien, auch ''.'' und ''..'' --- aktuelles und übergeordnetes Verzeichnis.
 +Als Pfadtrenner sind sowohl ''/'' als auch ''\'' nutzbar.
 +Der Dateiname ''p.filename()'' regulärer Dateien besteht oft aus zwei durch Punkt getrennten Teilen, ''p.stem()'' und ''p.extension()''.
 +
 +        Wurzelverzeichnis
 +        v              Dateiname 
 +      E:/temp/a/simple/example.txt
 +      /  ~~~~~~~~~~~~~ ------- ~~~
 +      LW  Relativpfad   Stamm  Erweiterung
 +
 +Über die Bestandteile eines Pfades kann iteriert werden.
 +<code cpp>
 +  for (const auto& e : fs::path("E:/temp/a/simple/example.txt")) 
 +    std::cout << e << ' ';  
 +</code>
 +Die Ausgaben erscheinen als "quoted" strings:
 +    "E:" "/" "temp" "a" "simple" "example.txt"
 +
 +==== Berechtigungen ====
 +Dateien und Verzeichnisse können nur von bestimmten Nutzern gelesen, geschrieben und ausgeführt werden. 
 +Diese Berechtigungen lassen sich in einer kurzen Zeichenkette zusammenfassen 
 +(hier ohne ''set_uid'', ''set_gid'' und ''sticky_bit''):
 +<code cpp> 
 +auto perm_string(fs::perms p)
 +{
 +  auto table = 
 +  { std::pair
 +    {fs::perms::owner_read,  "-r"},
 +    {fs::perms::owner_write, "-w"},
 +    {fs::perms::owner_exec,  "-x"},
 +    {fs::perms::group_read,  "-r"},
 +    {fs::perms::group_write, "-w"},
 +    {fs::perms::group_exec,  "-x"},
 +    {fs::perms::others_read, "-r"},
 +    {fs::perms::others_write,"-w"},
 +    {fs::perms::others_exec, "-x"},
 +  };
 +  auto sign = [p] (auto flag, const char s[]) { return s[(p & flag) != fs::perms::none]; };
 +  std::ostringstream os;
 +  for (auto&& [flag, s] : table) os << sign(flag, s);
 +  return os.str();   
 +}
 +</code>
 +
 +==== Dateieigenschaften abfragen ====
 +Für einen vorgegebenen Pfad lassen sich alle Eigenschaften anzeigen: 
 +<code cpp>
 +void show(fs::path path)
 +{
 +  if (!fs::exists(path))
 +  {
 +    std::cout << path << " file does not exist\n";
 +    return; 
 +  }
 +  auto perms = perm_string(fs::status(path).permissions());
 +  using clock = std::chrono::system_clock;
 +  auto time = clock::to_time_t(fs::last_write_time(path)); 
 +  auto timestr = std::string(std::asctime(std::localtime(&time)));
 +  timestr.pop_back(); // get rid of '\n';
 +  std::cout << (fs::is_directory(path)? "d" : " ") << perms << " " << timestr << " "
 +    << (fs::is_regular_file(path)? std::to_string(fs::file_size(path)) + " " : "")  
 +    << path << '\n';
 +}
 + 
 +void ls()
 +{
 +  auto p = fs::current_path();
 +  show(p);
 +  for (auto&& entry : fs::directory_iterator(p))
 +    show(entry);
 +}    
 +</code>
 +Mit einem ''fs::directory_iterator'' kann ein gesamtes Verzeichnis durchlaufen werden, 
 +mit ''fs::recursive_directory_iterator'' einschließlich Unterverzeichnisse.
 +Ein [[https://wandbox.org/permlink/biSXHJpohRgu2CBb|Demoprogramm]] liefert die ein wenig an das Kommando ''ls'' erinnernde Ausgabe:
 +<file>
 +drwx------ Mon Feb  5 00:26:47 2018 "/home/jail"
 + rw------- Mon Feb  5 00:26:45 2018 1395 "/home/jail/prog.cc"
 + rwxr-xr-x Mon Feb  5 00:26:47 2018 2648576 "/home/jail/prog.exe"</file>
 +===== Dateiarbeit =====
 +
 +==== Verzeichnisse anlegen ====
 +<code cpp>
 +void create()
 +{
 +  fs::create_directories("sandbox/a/b");
 +  std::ofstream("sandbox/file1.txt") << "Hello";
 +  std::ofstream("sandbox/a/file2.txt") << "World";
 +}
 +</code>
 +==== kopieren ====
 +<code cpp>
 +void copy()
 +{
 +  fs::create_directories("sandbox/c");
 +  fs::rename("sandbox/a/file2.txt", "sandbox/a/file3.txt");
 +  fs::copy("sandbox/a/file3.txt", "sandbox/c/file3.txt");
 +  fs::copy("sandbox/a", "sandbox/copy",
 +    fs::copy_options::recursive |
 +    fs::copy_options::directories_only); // erstellt nur Verzeichnisse
 +}
 +</code>
 +==== löschen ====
 +<code cpp>
 +void destroy()
 +{
 +  fs::remove("sandbox/file1.txt"); 
 +  fs::remove("sandbox/a/b"); 
 +  fs::remove_all("sandbox");
 +}
 +</code>
 +==== Ausnahmen und Fehlerbehandlung ====
 +Im Fehlerfall können die Funktionen eine Ausnahme vom Typ ''fs::filesystem_error'' werfen.
 +Zu allen Funktionen und Methoden exstieren Varianten, 
 +die Fehler über eine ''std::error_code''-Referenz aus dem Header [[system_error]]
 +als zusätzlichen, letzten Parameter mitteilen.
 +
  

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki