No se puede leer correctamente todo el archivo utilizando fseek() y fread()
Tengo un archivo con el código fuente de un shader que quiero leer y se ve así:
“`cpp
<h1>version 460 core</h1>
layout(location = 0) in vec2 pos;
layout(location = 1) in vec3 color;
layout(location = 0) out vec3 fragColor;
uniform float rand;
out gl<em>PerVertex
{
vec4 gl</em>Position;
float gl<em>PointSize;
float gl</em>ClipDistance[];
};
void main()
{
fragColor = color * rand;
gl<em>Position = vec4(pos.x + 0.5 * gl</em>InstanceID, pos.y, 0, 1);
}
“`
Primero averiguo el tamaño de mi archivo:
cpp
fseek(m_file, 0L, SEEK_END);
size_t size = ftell(m_file);
Esto devuelve 364. El problema es que si simplemente copio y pego el contenido del archivo en un string R"()"
y obtengo la longitud con strlen, devuelve 347.
Después de obtener el tamaño del archivo, intento leer todo el archivo:
cpp
fseek(m_file, 0, SEEK_SET);
size_t count = fread(buffer, 1, size, m_file);
donde buffer
está asignado con 364 bytes. Pero fread devuelve 347 y feof(m_file) devuelve true. Como resultado, obtengo esto:
(El explorador de archivos también muestra que el tamaño del archivo es 364).
Sin embargo, cuando leo el mismo archivo en un string usando std::ifstream
, todo funciona correctamente:
cpp
std::ifstream ifs(filename);
std::string content((std::istreambuf_iterator<char>(ifs)),
(std::istreambuf_iterator<char>()));
auto size = content.size();
y el tamaño es igual a 347.
La pregunta es: ¿estoy haciendo algo mal o Windows/fseek simplemente muestra incorrectamente el tamaño del archivo?
davy.ai
Parece que el problema no está en tu código, sino en la forma en que Windows calcula el tamaño del archivo. Windows cuenta el marcador de fin de archivo (EOF, por sus siglas en inglés) como parte del tamaño del archivo, mientras que
strlen
ystd::string
no lo hacen. Esta discrepancia en el conteo resulta en la discrepancia en el tamaño del archivo entre lo que se informa porftell
y lo que se informa porstrlen
/std::string size
.Por lo tanto, no hay nada malo en tu código y el comportamiento que estás observando es esperado. Se recomienda usar
std::ifstream
para leer archivos en cadenas de texto y asegurar el manejo adecuado del marcador EOF.