Linux初学第二天<文件的写入/读取/关闭>

文件的写入(write)

昨天已经学习了文件的打开及创建,及使用open函数,传递不同的参数可以实现文件的打开及创建,并赋予文件的权限,今天延续昨天的学习内容。
文件的写入及读取都需要添加一个头文件:

#include <unistd.h>

先说说文件的写入函数:write。

write() 文件写入函数

函数原型: ssize_t write(int fd, const void *buf, size_t count);

返回值: 返回实际写入数据的大小,如果count 的值远远大于buf的大小,返回的只有buf的 大小值。
说明: 写入 count个字节的 buffd描述符指向的文件。
用法: 把open打开或创建的文件的描述符传给 writefd,并且定义一个指针传给 buf,count为buf的大小,可以用strlen()函数计算buf的大小。例如:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
        int fd;
        char *buf="很帅!";
        fd=open("./file",O_RDWR);
//       ssize_t write(int fd, const void *buf, size_t count);  
        int n_write=write(fd,buf,strlen(buf));
        if(n_write!=-1){
                printf("write %d byte to file\n",n_write);
        }
}

运行结果:
在这里插入图片描述
打开了file之后:
在这里插入图片描述
再说说read函数

read() 文件读取函数

函数原型:ssize_t read(int fd, void *buf, size_t count);

返回值: 返回读取fd指向文件的 count个字节
说明: 读取fd指向的文件的count个字节的内容,存入buf
用法: 把open的返回值(即fd文件描述符)传递给read的fd,定义一个指针来存放buf的内容,count赋值大小。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
        int fd;
        char *buf="很帅!";
        fd=open("./file",O_RDWR);
        int n_write=write(fd,buf,strlen(buf));//先写入内容
//      ssize_t read(int fd, void *buf, size_t count);
		close(fd);  //先关闭文件
		fd=open("./file",O_RDWR);//再打开文件
        char *Read_Buf;
        Read_Buf=(char *)malloc(sizeof(char)* n_write+1);//分配空间给指针
        int n_Read=read(fd,Read_Buf,n_write);//读取内容
        printf("Read  %d byte to file,%s\n",n_Read,Read_Buf);
        close(fd);  //关闭文件
        return 0;
}

在程序中可以看到,我们在write之后并没有直接read,那是因为read需要文件内的 光标在我们所要读取的内容之前(这里为文件的头部),而write后的光标总是在文件的尾部,所以直接在write之后读取的话,不会读取到内容,返回值为0。但是先关闭文件(close)再打开文件(open)后,光标就在文件的头部,这样才能正确的读取。但是这个操作光标的方法不仅土得掉渣,还不灵活,这就需要光标操作函数 lseek()

lseek() 光标操作函数

函数原型:off_t lseek(int fd, off_t offset, int whence);

返回值: 返回一个相对于文件头的偏移值;
参数说明:
fd : 需要操作光标的文件的描述符(非负整数);
offset :相对于whence的偏移值:负数——往前偏移、正数——往后偏移;
whence :光标的位置设定:SEEK_SET 文件头部、SEEK_END文件尾部、SEEK_COUNT当前位置。
用法: 在fd指向的文件中,光标从whence的位置,往前或者往后偏移offset个字节。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
        int fd;
        char *buf="很帅!";
        fd=open("./file",O_RDWR);
//       ssize_t write(int fd, const void *buf, size_t count);  
        int n_write=write(fd,buf,strlen(buf));
        if(n_write!=-1){
                printf("write %d byte to file\n",n_write);
        }
//      off_t lseek(int fd, off_t offset, int whence);
        lseek(fd,-6,SEEK_END);//从尾部向前偏移6个字节
//      ssize_t read(int fd, void *buf, size_t count);
        char *Read_Buf;
        Read_Buf=(char *)malloc(sizeof(char)* n_write+1);
        int n_Read=read(fd,Read_Buf,n_write);
        printf("Read  %d byte to file,%s\n",n_Read,Read_Buf);
        close(fd);
        return 0;
}

也可以利用lseek函数来计算文件的大小,这么用:

int n_offset=0;
n_offset=lseek(fd,0,SEEK_END);//

因为lseek的返回值是相对于文件头的偏移值,所以lseek从头部到尾部的偏移值就算出来了。

close() 关闭文件函数

函数原型: int close(int fd);

说明: 关闭fd指向的文件;
当我们从open到write/read,后一定要用close来关闭文件,这样才完成操作文件的基本流程,也防止程序出错及文件丢失。至于为什么,这涉及到文件操作的原理。

文件的操作原理

文件描述符

1. 文件描述符是一个非负整数,当打开一个现存的文件或创建一个新文件时,内核会向进程返回一个文件描述符,当读写一个文件时,用open()或者creat返回的文件描述符标识该文件,作为参数传递给write和read。
2. 在UNIX Shell中,文件描述符有3个已经定义的宏,它们分别替代了0、1、2:
STDIN_FILENO: 替代了 0 :为标准输入文件,传递给read的时候,可以获取键盘的输入,作用相当于scanf;
STDOUT_FILENO: 替代了 1:为标准输出文件,传递给write 可以打印输出,相当于printf;
STDRR_FILENE: 替代了 2 :为标准错误文件,以后可以用来作错误提示。
这就解释了为什么我们在创建文件的时候,文件描述符总是先从3开始
3. 文件描述符的作用域是当前的进程,出了这个进程后,这个文件描述符就没有意义了,也就是说这个文件描述符不起作用了。

静态文件及动态文件

静态文件

静态文件存于磁盘当中,比如我们电脑桌面的文件夹,就属于静态文件。

动态文件

当我们open一个静态文件之后,Linux内核会产生一个结构体来描述这个文件,结构体当中可能文件名,文件大小、文件内容等元素;而其中的文件内容就是我们在使用 write 或者read所操作的文件,就是动态文件。它在close(关闭文件 )之前会存放在内存当中,直到执行close之后,才会存放在磁盘当中,变成静态文件。这就是为什么我们在write/read之后要close的原因

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值