如何使用C ++ 17获得以字节为单位的文件大小

Jon*_*ein 93 c++ filesize c++-standard-library c++17

我应该知道,特定操作系统是否存在陷阱?

有很多重复(12345这个问题),但他们在几十年前进行了解答。在许多这些问题中,投票率很高的答案今天是错误的。

.sx上其他(旧质量检查)的方法

  • stat.h(wrapper sprintstatf),使用syscall

  • tellg(),根据定义返回一个位置,不一定返回bytes。返回类型不是int

Hol*_*Cat 119

<filesystem>(在C ++ 17中添加)使此操作非常简单

#include <cstdint>
#include <filesystem>

// ...

std::uintmax_t size = std::filesystem::file_size("c:\\foo\\bar.txt");
Run Code Online (Sandbox Code Playgroud)

如评论中所述,如果您打算使用此功能来决定从文件中读取多少字节,请记住...

...除非文件是由您专门打开的,否则可以在请求文件的时间与尝试从文件中读取数据的时间之间更改文件的大小。
–尼科尔·波拉斯(Nicol Bolas)

  • @Fureeish`std :: size_t`仅在保存内存对象的最大大小时才需要。文件可能会很大, (38认同)
  • @Fureeish好吧,在32位Windows(我假设在大多数现代的32位平台上)中,`size_t'是32位,而'uintmax_t'是64位。 (26认同)
  • @HolyBlackCat:最好说一下文件系统是全局的,因此,除非您“专有地”打开文件,否则文件的大小可以在您要求的时间和尝试的时间之间进行更改。从中读取数据。 (16认同)
  • 我使用@Fureeish只是因为那是`file_size`返回的类型。我也看起来有点怪异。 (13认同)
  • 有点题外话:有没有一个世界,其中std :: uintmax_t可以拥有比std :: size_t更大的值?如果不是,为什么不使用`std :: size_t`,可以说它更容易识别?+1,顺便说一句 (11认同)
  • 我们不能只同意`auto size = std :: filesystem :: file_size(“ c:\\ foo \\ bar.txt”);`吗? (6认同)
  • @RichardCritten,所以我评论的第一个问题的答案是“是”? (3认同)
  • @JonasStein 提到的重载会在错误时引发异常。另一个重载返回`static_cast&lt;uintmax_t&gt;(-1)`并将相应的错误存储到`ec`。 (2认同)
  • @NicHartley:然后,您已经破坏了自己的代码,因此,您在某种程度上都知道自己已经破坏了代码并拥有修复它的工具。随着其他进程的到来并改变了文件的大小,这两种情况都不是。因此,我们谈论的是非常不同的场景。 (2认同)

GOV*_*XIT 27

C ++ 17带来了std::filesystem简化文件和目录上许多任务的功能。您不仅可以快速获取文件大小及其属性,还可以创建新目录,遍历文件以及使用路径对象。

新的库为我们提供了两个可以使用的功能:

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

std::uintmax_t std::filesystem::directory_entry::file_size() const;
Run Code Online (Sandbox Code Playgroud)

中的第一个函数是自由函数std::filesystem,第二个函数是中的方法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';
}
Run Code Online (Sandbox Code Playgroud)

  • “这个”到底是什么?您能解释一下所有这些代码的用途吗,特别是当接受的答案使用更少的代码时? (2认同)