C ++ 17을 사용하여 파일 크기를 바이트 단위로 가져 오는 방법 이러한 많은 질문에서 매우 높은 투표를받은 답변은

특정 운영 체제에 대해 알아야 할 함정이 있습니까?

이 질문의 중복 ( 1 , 2 , 3 , 4 , 5 )이 많이 있지만 수십 년 전에 답변되었습니다. 오늘날 이러한 많은 질문에서 매우 높은 투표를받은 답변은 잘못된 것입니다.

.sx의 다른 (이전 QA) 메서드

  • stat.h (래퍼 sprintstatf ), syscall 사용

  • tellg () 는 정의에 따라 위치를 반환 하지만 반드시 bytes는 아닙니다 . 반환 유형이 아닙니다 int.



답변

<filesystem>(C ++ 17에 추가됨) 이것은 매우 간단 합니다.

#include <cstdint>
#include <filesystem>

// ...

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

주석에서 언급했듯이이 함수를 사용하여 파일에서 읽을 바이트 수를 결정하려면 다음 사항을 명심하십시오.

… 파일을 사용자가 독점적으로 열지 않는 한, 파일을 요청한 시간과 데이터를 읽으려는 시간 사이에 파일 크기를 변경할 수 있습니다.
– 니콜 볼 라스


답변

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';
}


답변