Linux文件写入读取与关闭(二)

文件的写入

//文件写入所需的头文件
#include <unistd.h>

write() 文件写入函数

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

返回值: 返回实际写入数据的大小,如果count 的值远远大于buf的大小,返回的只有buf的 大小值。
说明: 写入 count个字节的 buf给 fd描述符指向的文件。
用法: 把open打开或创建的文件的描述符传给 write的 fd,并且定义一个指针传给 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="this is my VMware Workstation!";
        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);
        }
        return 0}

可以看到这里count通过strlen(buf)写入32个字节,当count的值刚好等于buf的大小时。
运行结果:

在这里插入图片描述
打开文件:

在这里插入图片描述

当count大小不等于buf 的大小时

int n_write=write(fd,buf,100);//上面第14行,count由strlen(buf)变为100

当count的值超过buf的大小时,则会出现以下乱码
在这里插入图片描述

int n_write=write(fd,buf,10);//上面第14行,count由strlen(buf)变为10

当count的值小于buf的大小时,则会写入不全。

在这里插入图片描述


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 = "Sam Liu is a wonderful FAE!\n";
        fd = open("./file",O_RDWR);
        printf("open succeess:%d\n",fd);
//      ssize_t write(int fd, const void *buf, size_t count);
        int n_write = write(fd,buf,strlen(buf));//先写入内容
       
        close(fd);//先关闭文件
        fd = open("./file1",O_RDWR);//再打开文件
        
        char *readBuf;
        readBuf = (char*)malloc(sizeof(char)*n_write);//使用malloc分配空间给指针
//      ssize_t read(int fd, void *buf, size_t count);
        int n_read = read(fd,readBuf,n_write);//读取内容
		printf("read %d byte,context:%s",n_read,readBuf);
        close(fd);        
        return 0;
}

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

输出结果:
在这里插入图片描述


lseek() 光标操作函数

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

<参数说明>

返回值: 返回一个相对于文件头的偏移值

fd : 需要操作光标的文件的描述符(非负整数);

offset负数正数
相对于whence的偏移值往前偏移往后偏移
whenceSEEK_SETSEEK_ENDSEEK_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 = "Sam Liu is a wonderful FAE!\n";
        fd = open("./file",O_RDWR);
        printf("open succeess:%d\n",fd);
//      ssize_t write(int fd, const void *buf, size_t count);
        int n_write = write(fd,buf,strlen(buf));//先写入内容
       
//      off_t lseek(int fd, off_t offset, int whence);
        lseek(fd,-28,SEEK_END);//从尾部向前偏移28个字节   
//又或者 lseek(fd,0,SEEK_SET);//光标从头部开始,偏移0个字节
   
        char *readBuf;
        readBuf = (char*)malloc(sizeof(char)*n_write);//使用malloc分配空间给指针
//      ssize_t read(int fd, void *buf, size_t count);
        int n_read = read(fd,readBuf,n_write);//读取内容
		printf("read %d byte,context:%s",n_read,readBuf);
        close(fd);        
        return 0;
}

输出结果:
在这里插入图片描述

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

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

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


close() 关闭文件函数

//close()函数原型
int close(int fd)

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

文件的操作原理

文件描述符

Linux系统默认文件描述符

012
标志输入标准输出标准错误
  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的原因。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值