C 编程文件大小

Posted

技术标签:

【中文标题】C 编程文件大小【英文标题】:C programming File size [closed] 【发布时间】:2013-01-01 23:42:54 【问题描述】:

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

【问题讨论】:

你在closed 描述符上调用fstat,这是故意的吗?看来你应该改成close-ing createDescriptor... 【参考方案1】:

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

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

这将打印:

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

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

代码让我担心。

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

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 时,只需使用标准的&lt;stdio.h&gt; 函数:

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 无效函数(int openDescriptor) write(openDescriptor,"这将输出到 testfile.txt\n",36 ); $ 猫 teststr2.c #include #include 无效函数(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 "teststr2.c"

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

【讨论】:

如果字符串没有改变,不要为同一个字符串调用两次strlenstrlen 是一个相当“昂贵”的调用函数,因此应尽可能避免使用它 - 尽管对于常量,编译器可能会计算它,但风险是有人认为这也是一个变量的好计划 [我愿意同意对字符串使用硬编码常量比两次调用 strlen 更糟糕]。 @MatsPetersson:你没有注意。关键是字符串是恒定的。它也昂贵,与该程序执行的其他任务相比。 是的,而且我的建议还是不要为常量字符串调用strlen两次,因为有人会把它改成非常量字符串并继续调用strlen两次,然后你就没有得到编译器在编译期间计算它的同样好的副作用。 @MatsPetersson:是的,有很多人在不理解代码的情况下复制和粘贴代码。 (1) 我不在乎这些人。 (2) 这些人会犯其他更严重的错误,所以提前帮助他们是浪费时间。 (3) 代码在优化之前应该是正确的。 (4) 代码在优化之前应该被分析。为修改代码的理论上的未来情况优化未分析的代码是浪费时间。我不会鼓励程序员把时间浪费在可以和家人一起吃晚饭的事情上。 但是写size_t len = strlen(str); 并在两个地方使用 len 并不是特别困难 - 事实上,它更容易看出它在两个地方意味着相同的值。

以上是关于C 编程文件大小的主要内容,如果未能解决你的问题,请参考以下文章

Linux系统编程(文件)———CP指令判断文件大小

Linux编程问题 利用for循环将当前目录下的.c文件移到指定的目录下,并按文件大小排序,显示移

如何在目标c中获取mac中所有文件的大小[重复]

C 语言编程 — stat 文件操作

Linux文件大小 指令&编程

linux系统编程:用truncate调整文件大小