<Io.h> _filelength y _filelengthi64 siempre devuelve 0

votos
0

Estoy usando funciones io bajo nivel para buscar el tamaño de un archivo en bytes y escribirla en la salida estándar. Estoy usando ventanas 7 de 64 bits, y estoy usando Visual Studio 2017, el modo de depuración x64. Las funciones _filelength y _filelengthi64 son exclusivos de los sistemas operativos Windows, sin embargo, cuando los utilizo ambos devuelven un 0 para cualquier archivo que se pueden abrir. Aquí está el código completo, pero el problema sólo debe recaer _sopen_s()o _filelengthi64():

Encabezamiento

#pragma once

// Headers
#include <io.h>
#include <string.h>
#include <sys\stat.h>
#include <share.h>
#include <fcntl.h>
#include <errno.h>

//  Constants
#define stdout  1
#define stderr  2

//  Macros
#define werror_exit     { werror(); return 1; }
#define werr_exit(s)    { _write(stderr, (s), (unsigned int)strlen((s))); return 1; }

//  Declarations
extern void werror();
extern void wnum(__int64 num);

Fuente

#include readbinaryfile.h

int main(int argc, char **argv)
{
    int     fhandle;
    __int64 fsize;

    // open binary file as read only. deny sharing write permissions. allow write permissions if new file
    if (_sopen_s(&fhandle, argv[1], _O_RDONLY | _O_BINARY, _SH_DENYWR, _S_IWRITE) == -1)
        werror_exit
    else if (fhandle == -1)
        werr_exit(\nERROR: file does not exist...\n)

    if (fsize = _filelengthi64(fhandle) == -1)
    {
        if (_close(fhandle) == -1)
            werror_exit
        werror_exit
    }

    if (_close(fhandle) == -1)
        werror_exit

    // write the file size to stdout
    wnum(fsize);

    return 0;
}

// fetch the string representation of the errno global variable and write it to stderr
void werror()
{
    char    bufstr[95];
    size_t  buflen = 95; // MSDN suggested number for errno string length

    strerror_s(bufstr, buflen, errno);
    _write(stderr, bufstr, (unsigned int)buflen);

    _set_errno(0);
}

// recursively write the ascii value of each digit in a number to stdout
void wnum(__int64 num)
{
    if (num / 10 == 0)
    {
        _write(stdout, &(num += 48), 1);
        return;
    }

    wnum(num / 10);
    _write(stdout, &((num %= 10) += 48), 1);
}

He tratado de pasar muchas rutas de los archivos diferentes a argv[1]sin embargo, todos siguen mostrando una fsizede 0. En todos los casos, fhandlese le asignó un valor de 3 después de usar _sopen_s(), que no indica ningún error al abrir los archivos. He verificado el funcionamiento de wnum()y werror(). Agradezco la ayuda!

Publicado el 07/11/2018 a las 22:34
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
2

_filelengthi64(fhandle)no devuelve 0. La expresión _filelengthi64(fhandle) == -1, sin embargo, será (suponiendo una llamada con éxito), que se asigna a fsize. Usted está haciendo caso omiso de la precedencia de los operadores C , dictando que ==tiene mayor precedencia que =. Usted tendrá que utilizar paréntesis para cambiar la precedencia:

if ((fsize = _filelengthi64(fhandle)) == -1)
{
    ...

Si desea reducir la cantidad de energía mental requerido para escribir (y sobre todo leer) de código, por lo general es una buena idea para aislar la lógica de código normal de control de errores, por ejemplo:

// Normal code flow
fsize = _filelengthi64(fhandle);
// Error handling code
if (fsize == -1)
{
    ...
Respondida el 08/11/2018 a las 08:58
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more