<io.h> _filelength和_filelengthi64始终返回0

时间:2018-11-07 22:34:39

标签: c windows

我正在使用底层io函数来获取文件大小(以字节为单位)并将其写入stdout。我正在使用Windows 7 64bit,并且正在使用Visual Studio 2017 x64调试模式。函数_filelength和_filelengthi64是Windows操作系统专有的,但是当我使用它们时,它们为我打开的任何文件都返回0。这是完整的代码,但问题仅在于_sopen_s()_filelengthi64()

标题

#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);

来源

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

我尝试过将许多不同的文件路径传递给argv[1],但它们都仍然显示fsize为0。在所有这些情况下,fhandle在使用{后被赋值为3 {1}}表示打开文件时没有错误。我已经验证了_sopen_s()wnum()的操作。感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

_filelengthi64(fhandle)不返回0。但是,表达式_filelengthi64(fhandle) == -1将(假设调用成功)将被分配给fsize。您无视C operator precedence,而是指出==的优先级高于=。您将必须使用括号来更改优先级:

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

如果您想减少编写(尤其是阅读)代码所需的精力,通常将正常代码逻辑与错误处理隔离是一个好主意,例如:

// Normal code flow
fsize = _filelengthi64(fhandle);
// Error handling code
if (fsize == -1)
{
    ...