C编程文件大小
在创建文件并向其写入数据后,我试图获取文件的大小。我得到的值似乎与实际文件大小不符。这是我的节目。请告诉我如何以位、字节、千字节和兆字节显示文件大小。根据我的说法,文件大小应该是288位、36字节、0.03515626千字节和0.000034332兆字节C编程文件大小,c,file,filesize,C,File,Filesize,在创建文件并向其写入数据后,我试图获取文件的大小。我得到的值似乎与实际文件大小不符。这是我的节目。请告诉我如何以位、字节、千字节和兆字节显示文件大小。根据我的说法,文件大小应该是288位、36字节、0.03515626千字节和0.000034332兆字节 #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/sta
#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义PERMS 0777
int main(int argc,char*argv[])
{
int-createDescriptor;
开放描述符;
char fileName[15]=“Filename1.txt”;
乌马斯克(万);
if((openDescriptor=creat(fileName,PERMS))=-1)
{
printf(“创建%s时出错”,文件名);
退出(退出失败);
}
if(write(openDescriptor,“这将输出到testfile.txt\n”,36)!=36)
{
写入(2,“写入testfile.txt时出错”,43);
返回1;
}
如果((关闭(打开描述符))=-1)
{
写入(2,“错误关闭文件。\n”,19);
}
结构统计buf;
fstat(openDescriptor和buf);
int size=buf.st_size;
printf(“%d\n”,大小);
printf(“%u\n”,大小);
返回0;
}
函数的fstat()
有一个返回码,检查它。
int r = fstat(openDescriptor, &buf);
if (r) {
fprintf(stderr, "error: fstat: %s\n", strerror(errno));
exit(1);
}
这将打印:
error: fstat: Bad file descriptor
您可以这样做:
const char *str = "This will be output to testfile.txt\n";
if (write(fd, str, strlen(str)) != strlen(str))
它将编译成相同的机器代码,而且显然是正确的(与原始代码相反,原始代码需要计算字符串中的字符数以确定其是否正确)
更好的是,当您使用stderr
时,只需使用标准的
功能即可:
fprintf(stderr, "There was an error writing to %s: %s\n",
fileName, strerror(errno));
定义文件名时也会出现相同的错误
// 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]
,但最好让编译器来处理。使编译器的工作更简单没有任何好处,因为编译器可能没有更好的事情要做
关于机器代码:
$cat teststr.c
#包括
void func(int openDescriptor){
写入(openDescriptor,“这将输出到testfile.txt\n”,36);
}
$cat teststr2.c
#包括
#包括
void func(int openDescriptor){
const char*str=“这将输出到testfile.txt\n”;
写入(openDescriptor、str、strlen(str));
}
$cc-S-O2 teststr.c
$cc-S-O2测试str2.c
$diff teststr.s teststr2.s
1c1
<.file“teststr.c”
---
>.file“teststr2.c”
是的。如前所示,调用strlen()
实际上不会产生不同的机器代码。您在关闭
d描述符上调用fstat
,这是故意的吗?似乎您应该close
-ingcreateDescriptor
取而代之……如果字符串没有更改,请不要为同一字符串调用strlen
两次strlen
调用是一个相当“昂贵”的函数,因此应该尽可能避免使用它-虽然对于常量,编译器可能会计算它,但风险是有人认为这也是一个变量的好方案[我同意,对字符串使用硬编码常量比调用strlen两次差得多]马特森:你没注意。关键是字符串是常量。与此程序执行的其他任务相比,它也不昂贵。是的,我的建议仍然是不要为常量字符串调用strlen两次,因为有人会将其更改为非常量字符串并继续调用strlen两次,然后你就不会得到编译器在编译过程中计算代码的同样好的副作用。@MatsPeterson:是的,有很多人在不理解代码的情况下复制和粘贴代码。(1) 我不在乎这些人。(2) 这些人会犯其他更严重的错误,所以提前帮助他们是浪费时间。(3) 代码在优化之前应该是正确的。(4) 在优化代码之前,应该对其进行概要分析。在未来的理论案例中,如果代码被修改,那么优化未归档的代码是浪费时间的。我不会鼓励程序员在这些事情上浪费时间,因为他们可以花时间和家人一起吃饭在这两个地方使用len并不是太难——事实上,它更容易看出这两个地方的值是相同的。
// 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";
$ cat teststr.c
#include <unistd.h>
void func(int openDescriptor) {
write(openDescriptor,"This will be output to testfile.txt\n",36 );
}
$ cat teststr2.c
#include <string.h>
#include <unistd.h>
void func(int openDescriptor) {
const char *str = "This will be output to testfile.txt\n";
write(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"