我使用低级io函数获取文件的字节大小并将其写入标准输出。我使用的是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],但它们仍然显示0的fsize。在所有这些情况下,fhandle在使用_sopen_s()后被赋值为3,这表示打开文件时没有错误。我已经验证了wnum()werror()的操作。我很感激你的帮助!

最佳答案

_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)
{
    ...

关于c - <io.h> _filelength和_filelengthi64始终返回0,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53198923/

10-11 16:49