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


97

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

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

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

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

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



5
@LF:好,第一个问题已作为第二个问题的副本被关闭,这解释了为什么第一个问题所接受的答案是错误的。第三是问类似的tellg问题。唯一值得困扰的是第四个,而且这个问题并不好,因为它ofstream在问题及其答案中都谈论太多了。这个表达意图的要比其他表达要好得多(除了第一个是奇怪的)。
Nicol Bolas

6
请停止在问题和问题标题中添加无关的信息。年份无关紧要;这些技术是相关的。
elixenide '19

2
到底怎么了stat(2)?它变老了还是什么?
Lorinczy Zsigmond

1
@LorinczyZsigmond 怎么了?stat(2) 这不是语言标准的一部分。
Andrew Henle

Answers:


123

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

#include <cstdint>
#include <filesystem>

// ...

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

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

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


11
小题外话:有没有一个世界std::uintmax_t能够拥有比更大的价值std::size_t?如果不是,为什么不使用std::size_t,可以说是更容易识别的?答案+1,顺便说一句
Fureeish

13
我使用@Fureeish只是因为类型file_size返回。我也看起来有点怪异。
HolyBlackCat

39
std::size_t仅需要@Fureeish 才能保留内存对象的最大大小。文件可以大得多,
Richard Critten

26
@Fureeish好吧,在32位Windows(我假设在大多数现代的32位平台上)中,size_t是32位,并且uintmax_t是64位。
HolyBlackCat

16
@HolyBlackCat:最好说一下文件系统是全局的,因此,除非您完全打开文件,否则文件的大小可以在您要求的时间和尝试读取数据的时间之间进行更改。从中。
Nicol Bolas

28

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;

中的第一个函数是自由函数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';
}

2
“这个”到底是什么?您能否解释一下所有这些代码的用途,特别是当接受的答案使用少得多的代码时?
Nico Haase
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.