0

我试图在创建文件并向其写入数据后获取文件的大小。我得到的值似乎与实际文件大小不符。这是我的程序。请告诉我如何以位、字节、千字节和兆字节显示文件大小。根据我的说法,文件大小应该是 288 位、36 字节、0.03515626 千字节和 0.000034332 兆字节。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h> 
#include <sys/types.h> 
#define PERMS 0777

int main(int argc, char *argv[])
{
    int createDescriptor;
    int openDescriptor;

    char fileName[15]="Filename1.txt";
    umask(0000);

    if ((openDescriptor = creat(fileName, PERMS )) == -1)
    {
        printf("Error creating %s", fileName);
        exit(EXIT_FAILURE);
    }


    if(write(openDescriptor,"This will be output to testfile.txt\n",36 ) != 36)
    {
        write(2,"There was an error writing to testfile.txt\n",43);
        return 1;
    }

    if((close(openDescriptor))==-1)
    {
        write(2, "Error closing file.\n", 19);
    }
    struct stat buf;
    fstat(openDescriptor, &buf);
    int size=buf.st_size;
    printf("%d\n",size);
    printf("%u\n",size);

    return 0;
}
4

1 回答 1

7

fstat()函数有一个返回码,检查它。

int r = fstat(openDescriptor, &buf);
if (r) {
    fprintf(stderr, "error: fstat: %s\n", strerror(errno));
    exit(1);
}

这将打印:

错误:fstat:错误的文件描述符

是的...您关闭了文件描述符,它不再是文件描述符。你必须fstat()在调用之前close()

代码让我担心。

这是非常脆弱的,在任何情况下都不推荐:

if (write(openDescriptor,"This will be output to testfile.txt\n",36 ) != 36)

你可以这样做:

const char *str = "This will be output to testfile.txt\n";
if (write(fd, str, strlen(str)) != strlen(str))

它将编译为相同的机器代码,并且显然是正确的(与原始代码相反,您必须计算字符串中的字符数才能确定它是否正确)。

更好的是,当您使用 时stderr,只需使用标准<stdio.h>函数:

fprintf(stderr, "There was an error writing to %s: %s\n",
        fileName, strerror(errno));

定义时出现相同的错误fileName...

// You should never have to know how to count higher than 4 to figure
// out if code is correct...
char fileName[15]="Filename1.txt";

// Do this instead...
static const char fileName[] = "Filename1.txt";

这次你实际上算错了,[15]应该是[14],但最好把它留给编译器。使编译器的工作更容易没有任何好处,因为编译器可能没有更好的事情要做。

关于机器码:

$ 猫 teststr.c
#include <unistd.h>
无效函数(int openDescriptor){
    write(openDescriptor,"这将输出到 testfile.txt\n",36 );
}
$ 猫 teststr2.c
#include <string.h>
#include <unistd.h>
无效函数(int openDescriptor){
    const char *str = "这将被输出到 testfile.txt\n";
    写(openDescriptor,str,strlen(str));
}
$ cc -S -O2 teststr.c
$ cc -S -O2 teststr2.c
$ diff teststr.s teststr2.s
1c1
< .file "teststr.c"
---
> .file "teststr2.c"

是的。如图所示,调用strlen()实际上并不会产生不同的机器代码。

于 2013-01-01T23:52:33.400 回答