我正在使用底层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()
的操作。感谢您的帮助!
答案 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)
{
...