webentwicklung-frage-antwort-db.com.de

So ermitteln Sie die Dateigröße in Bytes mit C ++ 17

Gibt es Fallstricke für bestimmte Betriebssysteme, die ich kennen sollte?

Es gibt viele Duplikate ( 1 , 2 , , 4 , 5 ) von dieser Frage wurden sie aber vor Jahrzehnten beantwortet. Die sehr hoch bewerteten Antworten in vielen dieser Fragen sind heute falsch.

Methoden von anderen (alten QA) auf .sx

  • stat.h (Wrapper sprintstatf ) verwendet syscall

  • tellg () , gibt per Definition eine Position zurück, aber nicht unbedingt Bytes . Der Rückgabetyp ist nicht int.

93
Jonas Stein

<filesystem> (hinzugefügt in C++ 17) macht dies sehr einfach .

#include <cstdint>
#include <filesystem>

// ...

std::uintmax_t size = std::filesystem::file_size("c:\\foo\\bar.txt");

Wenn Sie diese Funktion verwenden möchten, um zu entscheiden, wie viele Bytes aus der Datei gelesen werden sollen, denken Sie daran, dass ...

... wenn die Datei nicht ausschließlich von Ihnen geöffnet wird, kann ihre Größe zwischen dem Zeitpunkt, zu dem Sie danach fragen, und dem Zeitpunkt, zu dem Sie versuchen, Daten daraus zu lesen, geändert werden.
- Nicol Bolas

119
HolyBlackCat

C++ 17 bringt std::filesystem, das viele Aufgaben in Dateien und Verzeichnissen rationalisiert. Sie können nicht nur schnell die Dateigröße und ihre Attribute abrufen, sondern auch neue Verzeichnisse erstellen, Dateien durchlaufen und mit Pfadobjekten arbeiten.

Die neue Bibliothek bietet uns zwei Funktionen, die wir verwenden können:

std::uintmax_t std::filesystem::file_size( const std::filesystem::path& p );

std::uintmax_t std::filesystem::directory_entry::file_size() const;

Die erste Funktion ist eine freie Funktion in std::filesystem, die zweite ist eine Methode in directory_entry.

Jede Methode hat auch eine Überladung, da sie eine Ausnahme auslösen oder einen Fehlercode zurückgeben kann (über einen Ausgabeparameter). Unten finden Sie den Detailcode, in dem alle möglichen Fälle erläutert werden.

#include <chrono>
#include <filesystem>  
#include <iostream>

namespace fs = std::filesystem;

int main(int argc, char* argv[])
{
    try
    {
        const auto fsize = fs::file_size("a.out");
        std::cout << fsize << '\n';
    }
    catch (const fs::filesystem_error& err)
    {
        std::cerr << "filesystem error! " << err.what() << '\n';
        if (!err.path1().empty())
            std::cerr << "path1: " << err.path1().string() << '\n';
        if (!err.path2().empty())
            std::cerr << "path2: " << err.path2().string() << '\n';
    }
    catch (const std::exception& ex)
    {
        std::cerr << "general exception: " << ex.what() << '\n';
    }

    // using error_code
    std::error_code ec{};
    auto size = std::filesystem::file_size("a.out", ec);
    if (ec == std::error_code{})
        std::cout << "size: " << size << '\n';
    else
        std::cout << "error when accessing test file, size is: " 
              << size << " message: " << ec.message() << '\n';
}
27
GOVIND DIXIT