【Linux】系统文件的读写

什么是文件?

  • 文件=内容+属性
  • 当文件没有被操作的时候,一般文件还是在磁盘当中。
  • 文件操作=文件内容的操作+文件属性的操作,文件操作有可能即改变内容,又改变属性。
  • 文件操作其实就是把内容和属性加载到内存当中。

打开文件其实都是系统来进行操作,都是调用系统提供的函数,就算是语言层面的操作文件的函数也是在内部调用了系统函数。

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属性,就会在每次写入之前清空文件内容。

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值