特定のオペレーティングシステムの落とし穴はありますか。
多くの重複があります( 1 、 2 、、 4 、 5 )この質問のうち、彼らは数十年前に回答されました。これらの質問の多くで投票数が非常に多い回答は、今日間違っています。
stat.h (ラッパー sprintstatf )、syscallを使用
tellg() 、定義ごとにapositionを返しますが、必ずしもバイトではありません。戻り値の型はint
ではありません。
<filesystem>
(C++ 17で追加)は、これを 非常に簡単 にします。
#include <cstdint>
#include <filesystem>
// ...
std::uintmax_t size = std::filesystem::file_size("c:\\foo\\bar.txt");
コメントで述べたように、この関数を使用してファイルから読み取るバイト数を決定する場合は、次の点に注意してください...
...ファイルがユーザーによって排他的に開かれていない限り、ファイルのサイズは、ファイルを要求してからデータを読み取ろうとするまでの間に変更できます。
–ニコルボーラス
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';
}