Cómo obtener el tamaño del archivo en bytes con C++17

5 minutos de lectura

avatar de usuario
jonas stein

¿Existen trampas para sistemas operativos específicos que deba conocer?

Hay muchos duplicados (1, 2, 3, 4, 5) de esta pregunta, pero fueron respondidos hace décadas. Las respuestas muy votadas en muchas de estas preguntas son incorrectas hoy.

Métodos de otros (antiguos controles de calidad) en .sx

  • stat.h (envoltura sprintstatf), utiliza llamada al sistema

  • contar()devuelve por definición a posición pero no necesariamente bytes. El tipo de retorno no es int.

  • Entrante para 10: es.cppreference.com/w/cpp/header/filesystem

    – Richard Critten

    30 de junio de 2019 a las 20:36

  • @LF: Bueno, la primera pregunta se cerró como un duplicado de la segunda, lo que explica por qué la respuesta aceptada en la primera Está Mal. El tercero está preguntando acerca de similares tellg problemas. El único con el que vale la pena molestarse es el cuarto, y ese no es muy bueno, ya que habla demasiado sobre ofstream, tanto en la pregunta como en sus respuestas. Este es mucho mejor para expresar la intención que los demás (excepto el primero, que está extrañamente cerrado).

    – Nicolás Bolas

    1 de julio de 2019 a las 5:06


  • Deje de agregar información irrelevante a su pregunta y al título de la pregunta. El año es irrelevante; las tecnologías son relevantes.

    – elixenida

    1 de julio de 2019 a las 21:08

  • Qué hay de malo en stat(2) ¿de todos modos? ¿Ha envejecido demasiado o qué?

    – Lorinczy Zsigmond

    2 de julio de 2019 a las 12:11

  • @LorinczyZsigmond Qué hay de malo en stat(2) No es parte del estándar del lenguaje.

    –Andrew Henle

    2 de julio de 2019 a las 13:31

avatar de usuario
santonegrogato

<filesystem> (agregado en C++ 17) hace esto muy directo.

#include <cstdint>
#include <filesystem>

// ...

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

Como se indica en los comentarios, si planea usar esta función para decidir cuántos bytes leer del archivo, tenga en cuenta que…

…a menos que el archivo sea abierto exclusivamente por usted, su tamaño se puede cambiar entre el momento en que lo solicita y el momento en que intenta leer los datos del mismo.
– Nicolás Bolas

  • Pequeño offtopic: ¿existe un mundo donde std::uintmax_t será capaz de contener valores mayores que std::size_t? Si no, ¿por qué no usar std::size_t, ¿cuál podría decirse que es más reconocible? +1 en la respuesta, por cierto

    – Furioso

    30 de junio de 2019 a las 20:39

  • @Fureeish lo usé solo porque ese es el tipo file_size devoluciones. A mí también me parece un poco raro.

    – Santo Gato Negro

    30 jun 2019 a las 20:40


  • @Fureeish std::size_t solo se requiere para contener el tamaño máximo de los objetos en memoria. Los archivos pueden ser considerablemente más grandes,

    – Richard Critten

    30 de junio de 2019 a las 20:42


  • @Fureeish Bueno, en Windows de 32 bits (y supongo que en la mayoría de las plataformas modernas de 32 bits) size_t es de 32 bits y uintmax_t es de 64 bits

    – Santo Gato Negro

    30 de junio de 2019 a las 20:43


  • @HolyBlackCat: Sería bueno decir algo sobre el hecho de que el sistema de archivos es global y, por lo tanto, a menos que el archivo sea exclusivamente abierto por usted, su tamaño se puede cambiar entre el momento en que lo solicita y el momento en que intenta leer los datos de él.

    – Nicolás Bolas

    1 de julio de 2019 a las 4:59

avatar de usuario
GOVIND DIXIT

C++17 trae std::filesystem que agiliza muchas tareas en archivos y directorios. No solo puede obtener rápidamente el tamaño del archivo, sus atributos, sino también crear nuevos directorios, iterar a través de archivos, trabajar con objetos de ruta.

La nueva biblioteca nos da dos funciones que podemos usar:

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

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

La primera función es una función libre en std::filesystemel segundo es un método en directory_entry.

Cada método también tiene una sobrecarga, ya que puede lanzar una excepción o devolver un código de error (a través de un parámetro de salida). A continuación se muestra el código detallado que explica todos los casos posibles.

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

  • ¿Qué es exactamente “esto”? ¿Puede explicar para qué se usa todo este código, especialmente cuando la respuesta aceptada usa mucho menos código?

    –Nico Haase

    2 de julio de 2019 a las 15:24

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad