web-dev-qa-db-ja.com

C ++ 17でファイルサイズをバイト単位で取得する方法

特定のオペレーティングシステムの落とし穴はありますか。

多くの重複があります( 12 、、 45 )この質問のうち、彼らは数十年前に回答されました。これらの質問の多くで投票数が非常に多い回答は、今日間違っています。

.sx上の他の(古いQAの)メソッド

  • stat.h (ラッパー sprintstatf )、syscallを使用

  • tellg() 、定義ごとにapositionを返しますが、必ずしもバイトではありません。戻り値の型はintではありません。

93
Jonas Stein

<filesystem>(C++ 17で追加)は、これを 非常に簡単 にします。

#include <cstdint>
#include <filesystem>

// ...

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

コメントで述べたように、この関数を使用してファイルから読み取るバイト数を決定する場合は、次の点に注意してください...

...ファイルがユーザーによって排他的に開かれていない限り、ファイルのサイズは、ファイルを要求してからデータを読み取ろうとするまでの間に変更できます。
–ニコルボーラス

119
HolyBlackCat

C++ 17はstd::filesystemを提供し、ファイルとディレクトリに関する多くのタスクを合理化します。ファイルサイズとその属性をすばやく取得できるだけでなく、新しいディレクトリを作成したり、ファイルを反復処理したり、パスオブジェクトを操作したりすることもできます。

新しいライブラリには、使用できる2つの関数があります。

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

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

最初の関数はstd::filesystemのフリー関数で、2番目の関数はdirectory_entryのメソッドです。

各メソッドには、例外をスローしたり、エラーコードを(出力パラメーターを介して)返したりする可能性があるため、オーバーロードもあります。以下は、考えられるすべてのケースを説明する詳細コードです。

#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