什么是文件?
- 文件=内容+属性
- 当文件没有被操作的时候,一般文件还是在磁盘当中。
- 文件操作=文件内容的操作+文件属性的操作,文件操作有可能即改变内容,又改变属性。
- 文件操作其实就是把内容和属性加载到内存当中。
打开文件其实都是系统来进行操作,都是调用系统提供的函数,就算是语言层面的操作文件的函数也是在内部调用了系统函数。
fopen、fwrite、fread
FILE * fopen ( const char * filename, const char * mode );
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
#include<stdio.h>
int main(void)
{
FILE* fp=fopen("myfile.txt","w");
if(fp==NULL)
{
printf("fopen error!\n");
}
const char* msg="hello world\n";
int count=5;
while(count--)
{
fwrite(msg,strlen(msg),1,fp);
}
fclose(fp);
return 0;
}
自动创建myfile.txt
文件并且进行写入。
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
返回成功读取的元素总数
#include <stdio.h>
int main()
{
FILE *fp = fopen("myfile.txt", "r");
if (!fp)
{
printf("fopen error!\n");
}
char buf[1024];
const char *msg = "hello bit!\n";
while (1)
{
size_t s = fread(buf,1,strlen(msg), fp);
if (s > 0)
{
buf[s] = 0;
printf("%s", buf);
}
if (feof(fp))
{
break;
}
}
fclose(fp);
return 0;
}
追加-a
追加不会清空文件,而是每一次写入都是从文件结尾接着写。
如果是写的方式,下一次会覆盖掉原来的文件再进行写入。
但如果是以追加a的方式进行写入的话就不会
读取-r
#include <stdio.h>
int main()
{
FILE *fp = fopen("myfile.txt", "r");
if (fp == NULL)
{
perror("fopen"); // 报错
return 1;
}
// 进行文件操作
while (1)
{
char line[128];
if (fgets(line, sizeof(line), fp) == NULL)//从fp当中读取放入line当中
break;
else
{
printf("%s", line);
}
}
fclose(fp); // 关闭文件
return 0;
}
输出信息到显示器的方法
#include <stdio.h>
#include <string.h>
int main()
{
const char *msg = "hello fwrite\n";
fwrite(msg, strlen(msg), 1, stdout);
printf("hello printf\n");
fprintf(stdout, "hello fprintf\n");
......
return 0;
}
操作系统的读写方式
打开文件open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
pathname
为文件路径flags
为打开方式mode
为默认权限
O_RDONLY
: 只读打开O_WRONLY
: 只写打开O_RDWR
: 读,写打开O_CREAT
:如果文件不存在,就要创建这个文件,并且需要传递mode
参数设置初始权限O_APPEND
:追加写O_TRUNC
:清空
如果一个文件要创建并且使用追加写可以这样传参:O_CREAT|O_APPEND
。
读文件read
从文件描述符fd
指向的文件当中读取,把读取到的数据写入buf
,写入的大小为count
。
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd=open("myfile.txt",O_RDONLY);//设置为只读
char* buff[1024];//要写入buff
ssize_t s=read(fd,buff,sizeof(buff)-1);//Linux下是没有'\0'的
if(s>0)
{
buff[s]='\0';
printf("%s\n",buff);
}
return 0;
}
如果使用使用了O_CREATE
就一定要自己设置mode
默认文件权限
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd=open("test.txt",O_CREAT|O_WRONLY|O_APPEND);
return 0;
}
可以看到test.txt
文件的权限是乱码。
初始化文件权限。
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd=open("test.txt",O_CREAT|O_WRONLY|O_APPEND,0666);
return 0;
}
但最终的结果好像不是0666
,这是由于umask
影响了最终的结果。
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
umask(0);
int fd=open("test.txt",O_CREAT|O_WRONLY|O_APPEND,0666);
return 0;
}
写文件write
把buf
中的内容写入到文件描述符fd
指向的文件当中,大小为count
个,返回值代表实际写入了多少个字节。
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
char* buf="test write";
int fd=open("myfile.txt",O_WRONLY);
ssize_t s=write(fd,buf,strlen(buf));
if(s==0)
{
printf("error\n");
}
return 0;
}
这是文件的原内容
执行代码之后变为
可以看出,是直接覆盖原内容,但还有d!!!
没有覆盖掉,就还留在文件当中。
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
char* buf="test write";
int fd=open("myfile.txt",O_WRONLY|O_APPEND);
ssize_t s=write(fd,buf,strlen(buf));
if(s==0)
{
printf("error\n");
}
return 0;
}
增加一个追加属性就不会覆盖掉了。
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
umask(0);
int fd=open("test.txt",O_CREAT|O_WRONLY|O_APPEND|O_TRUNC,0666);
char* buf="test!!! aaa";
ssize_t s=write(fd,buf,strlen(buf));
return 0;
}
如果添加一个O_TRUNC
属性,就会在每次写入之前清空文件内容。